繁体   English   中英

为什么在我的readyState逻辑中document.body为null?

[英]Why is document.body null with my readyState logic?

我正在尝试尽快将iframe元素附加到document.body中。

在所有4种主要浏览器(Chrome,Safari,FF,IE等各种版本)中都会出现错误报告,我们看到document.bodynull 我认为这是在我的JS文件被缓存并快速加载时发生的。

这是插入iframe的逻辑:

private loadIFrame(): void {
  switch (document.readyState) {
    case 'uninitialized':
    case 'loading':
    case 'loaded':
      window.addEventListener('DOMContentLoaded',
        this.appendIFrame.bind(this)
      )
      break
    case 'interactive':
    case 'complete':
    default:
      this.appendIFrame()
  }
}

private appendIFrame(): void {
  if (document.getElementById('iframeId')) {
    return
  }

  let iFrame: HTMLIFrameElement = document.createElement('iframe')
  iFrame.src = document.location.protocol + this.ORIGIN + '/iframe.html'
  iFrame.id = 'iframeId'

  // document.body is null here
  document.body.appendChild(iFrame)
}

我很难在干净的环境中重现该问题,这让我猜测这是如何在野外发生的。

我最初尝试了这种rreadyState逻辑,但是在loading状态下,我们看到IE中undefined document.body

private loadIFrame(): void {
  switch (document.readyState) {
    case 'uninitialized':
    case 'loading':
      window.addEventListener('DOMContentLoaded',
        this.appendIFrame.bind(this)
      )
      break
    case 'loaded':
    case 'interactive':
    case 'complete':
    default:
      this.appendIFrame()
  }
}

我目前的疑问线...

  1. 该问题是default情况吗? 我应该在那添加事件监听器吗? 我可以修改案例的顺序,以便事件监听器是默认的?
  2. DOMContentLoaded事件上的body是否可能为null
  3. 是否可能存在其他document.readyState值?

首先,如果您已经在检查readyState并确定要loaded它,那么为什么要在已经过去的那一刻设置一个事件处理程序( DOMContentLoaded )?

您可以这样做:

private loadIFrame(): void {
  switch (document.readyState) {
    case 'uninitialized':
    case 'loading':
    case 'loaded':
      this.appendIFrame.bind(this);
      break;
    case 'interactive':
    case 'complete':
    default:
      this.appendIFrame();
  }
}

接下来,您的事件处理程序注册错误。 .addEventListener()有3个参数,第三个可以是两个值之一:

  1. 事件名称(字符串)
  2. 回调函数(引用或内联函数)

    3a。 是否进入捕获阶段(布尔值-默认为false

    3b。 用于配置特征的选项对象(对象)

并且,在将接收事件的对象(在这种情况下为window addEventListener()上调用addEventListener()本身。

它应该是:

    window.addEventListener('DOMContentLoaded', function(){
      this.appendIFrame.bind(this);
    });

另外(FYI),您确实应该手动插入语句分号,而不要依赖自动插入,因为在某些情况下会导致错误。

我更新了逻辑, 几乎可以消除错误,但是当readyStateinteractive时,我仍然看到document.bodynull

一旦评估导致问题的特定浏览器方案,我将更新此帖子。

private loadIFrame(): void {
  switch (document.readyState) {
    case 'uninitialized':
    case 'loading':
    case 'loaded':
      document.addEventListener('DOMContentLoaded',
        this.appendIFrame.bind(this)
      )
      break
    case 'interactive':
    case 'complete':
    default:
      if(document.body) {
        this.appendIFrame()
      } else {
        window.addEventListener('load',
          this.appendIFrame.bind(this)
        )
      }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM