2017-06-29 15 views
0

iframe要素をできるだけ早くdocument.bodyに追加しようとしています。document.bodyが私のreadyStateロジックでnullになるのはなぜですか?

エラーレポートは、Chrome、Safari、FF、IE - さまざまなバージョンのすべての4つの主要ブラウザで表示されますが、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の状態では、はundefinedでした。問題はdefaultケース尋問の私の現在の行

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. ですか?イベントリスナーを追加する必要がありますか?イベントリスナーがデフォルトになるように、ケースの順序を変更できますか?
  2. DOMContentLoadedイベントでbodynullですか?
  3. document.readyStateの他の値が落ちている可能性はありますか?
+0

いくつかの参照を追加します。私はDOMContentLoadedがbodyが定義されることが保証されている最も早い時期に正しいイベントだと考えています:https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded また、すべてのブラウザが使用するわけではないことを認識してreadStatesの5つすべて。最新の標準は3つしかありません:https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState – theUtherSide

+0

「初期化されていない」状態と「ロードされた」状態を持つIEの参照です。私には、これは、解析が完了していないため、ボディが「ロード済み」状態で使用できないことを示しています。 https://msdn.microsoft.com/en-us/library/ms534359(v=vs.85).aspx – theUtherSide

答えて

0

私は、ロジックを更新し、私はほとんどエラーを排除するが、私はまだ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) 
     ) 
     } 
    } 
} 
1

まず、あなたはすでに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つの引数であり、第三は、2つの値のいずれかとすることができる。

  1. イベント名(文字列)
  2. コールバック関数(参照またはインライン関数)

    3A。キャプチャフェーズにフックするかどうか(ブール値 - デフォルトでfalse

    3bです。オプションは

そして、addEventListener()自体がイベント(この場合はwindowを)受け取るオブジェクトで呼び出される特性(オブジェクト)を設定するオブジェクト。

それは次のようになります。

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

また(FYI)、あなたは本当に手動でバグの原因となるエッジケースがあるとして、自動挿入に依存している文のセミコロンのあなたの終わりを挿入してはいけません。

+0

ありがとうございました!私の実際のコードは、クロスブラウザのラッパーメソッドを使用して、私はパラメータの翻訳を強化しました。私はポストを少し簡素化しようとしていた。 – theUtherSide

+0

同様に、私たちはASIを使用せず、TypeScriptをES5に変換するので、ソースにはセミコロンは含まれませんが、配布されたコードはそのままです。 – theUtherSide

+0

@theUtherSideそれでも、イベントが既に発生したと判断したら、そのイベントを処理しようとしているようです。私の最初のコード例はあなたのために働いていますか? –

関連する問題