簡體   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