私はこの質問をグーグルらに言い表すために多くの異なる方法を試しましたが、運がありませんでした。この質問のタイトルが問題のニュアンスを捉えているかどうかさえわかりません。説明してから実験を見せてみます。誰かが何が起こっているのかについての説明を指摘できるようになることを願っています。
与えられた:
- BODYが終了する前に、リモートスクリプト(B)を参照するドキュメントにスクリプト要素(私の好みの手法であるdocument.createElementを使用)をプログラムで挿入するスクリプト(A)があります。
- remote-script Bは、任意のコンテンツ( "hello、world"など)のdocument.writeを実行します。
- BODYの終了前とスクリプトAの直後に、ロードに時間がかかるリモートスクリプトを参照するスクリプト(C)があります(例:1s)
何が起こるかというと、Aが実行され、Bがドキュメントに挿入され、リソースのダウンロードが開始されます。Bがダウンロードしている間、遅延のため、Cは実行して待機します。Cが待機している間に、Bがダウンロードされて実行されます。まだDOMContentLoadedをヒットしていません。document.readyStateはまだ「ロード中」です。Bからのdocument.writeは無視されます。DOMContentLoaded後のように、ぐちゃぐちゃになりました。その後、Cはダウンロードを終了して実行します。
実験:
- 出典: http: //jsfiddle.net/jaknowlden/pwHG8/
- 直接試してみてください:http://jsfiddle.net/jaknowlden/pwHG8/show/
- ウォーターフォール:手動リンク[cl.ly/423P2M1d0r0e0k3h370g]
- リモートスクリプト:MANUAL LINK [thumblemonks.com/js/stackoverflow-script-b.js]
遅延を作成するためにCuzillionを使用しています。ウォーターフォールイメージをチェックアウトすると、console.logメッセージも表示されます。このメッセージは、DOMが「インタラクティブ」readyState(つまり、DOMContentLoaded)に達する前にすべてが実行されたことを示しています。
ブラウザでの出力として期待するのは次のとおりです。
TOP
hello, world
hello again, world
BOTTOM
出力として取得するものは次のとおりです。
TOP
hello, world
BOTTOM
私の実験では、AとCとして定義するものの間に別のスクリプトを追加したことに気付くでしょう。これをA'と呼んでください。これは、document.writeを含むテキストを含むスクリプト(つまり、リモートスクリプトではない)を動的に追加すると、A'のdoc.writeが機能することを示しています。
また、dummy.jsとCSSファイルはJSFiddleから取得されます。彼らは犯人ではありません。この問題はどこでも再現できます。
私が知っていること:
- CをIMGに置き換えても、問題はありません。
- CをIFRAMEに置き換えても、問題はありません。
- AをCの後に移動しても、問題はありません。
今:
おそらく、これには完全に正当な理由があります。私がテストしたすべてのブラウザはほぼ同じように動作するように見えるので、あるに違いありません。私が知りたいのはなぜですか?説明、ヒント、および/またはポインタは大歓迎です。「スペックにあるよ、ダンビー:)」のようなヒントでさえ、私は厚い肌を持っています。対処できます。
免責事項:私はdocument.writeを嫌います。私の意図は、いかなる方法でもその使用をサポートまたは強化することではありません。しかし、私の仕事の性質を考えると、私は今のところそれを回避する必要があり、この奇妙なことが私に起こりました。したがって、「document.writeを使用しないでください」というコメントは避けたいと思います。これは、私がすでに信じているからです:)