web-dev-qa-db-ja.com

docで書き込みを実行する:明示的に開かない限り、非同期で読み込まれた外部スクリプトからドキュメントに書き込むことはできません。

ページのロードが実行された後、次のような特定のスクリプトをロードしようとしています:

function downloadJSAtOnload(){
            var element = document.createElement("script");
            element.src = "scriptSrc";
            document.body.appendChild(element);
        }

         if (window.addEventListener)
                  window.addEventListener("load", downloadJSAtOnload, false);
            else if (window.attachEvent)
                  window.attachEvent("onload", downloadJSAtOnload);
            else window.onload = downloadJSAtOnload;

このスクリプトは、「scriptSrc」を実行およびダウンロードし、bodyタグの最後の直前に追加するように見えますが、コンソール(chrome)に次のメッセージ(エラーではありません)を生成します。

'Document'で 'write'の実行に失敗しました:明示的に開かない限り、非同期でロードされた外部スクリプトから文書に書き込むことはできません。

これはどういう意味ですか?そして、私は何か違うことをすることになっていますか?期待どおりの動作が得られますか?

63
Parijat Kalia

非同期的に読み込まれたスクリプトは、ドキュメントが完全に解析されて閉じられた後に実行される可能性があります。したがって、このようなスクリプトからdocument.write()を使用することはできません(技術的には可能ですが、必要なことはできません)。

DOM要素を作成し、document.write()または.appendChild()で特定の親に挿入するか、.innerHTMLまたは何らかのメカニズムを設定することにより、そのスクリプト内の.insertBefore()ステートメントを明示的なDOM操作に置き換える必要があります。そのような直接DOM操作のために。

たとえば、インラインスクリプトのこのタイプのコードの代わりに:

<div id="container">
<script>
document.write('<span style="color:red;">Hello</span>');
</script>
</div>

これを使用して、動的にロードされるスクリプトで上記のインラインスクリプトを置き換えます。

var container = document.getElementById("container");
var content = document.createElement("span");
content.style.color = "red";
content.innerHTML = "Hello";
container.appendChild(content);

または、コンテナに追加するだけのコンテンツが他にない場合は、次のようにできます。

var container = document.getElementById("container");
container.innerHTML = '<span style="color:red;">Hello</span>';
76
jfriend00

パーティーに少し遅れましたが、Kruxは Postscribe というスクリプトを作成しました。これを使用して、この問題を乗り越えることができました。

22
the0ther

これが私と同じ問題を抱えている人に役立つ場合に。 jQueryを介してフッターをWebページに取り込みました。そのフッターの中には、広告とリターゲティングのためのいくつかのGoogleスクリプトがありました。これらのスクリプトをフッターから移動し、ページに直接配置する必要があったため、通知がありませんでした。

2
mediaguru