web-dev-qa-db-ja.com

document.writeの代替手段は何ですか?

チュートリアルでは、_document.write_の使用方法を学びました。今、私はこれが多くの人に眉をひそめられていることを理解しています。 print()を試しましたが、それは文字通りプリンターに送信します。

それで、私が使用すべき代替案は何ですか、そしてなぜ_document.write_を使用すべきではないのですか? w3schoolsとMDNは両方とも_document.write_を使用します。

62
DarkLightA

document.writeの推奨代替手段として、 DOM操作 を使用して、ノード要素を直接照会し、DOMに追加できます。

11
Darin Dimitrov

HTMLが置き換えられる理由は、邪悪なJavaScript関数- document.write()が原因です。

それは間違いなく「悪い形」です。ページの読み込みで使用する場合にのみ、Webページで機能します。実行時に使用すると、ドキュメント全体が入力に置き換えられます。また、厳密なXHTML構造として適用する場合、有効なコードではありません。


問題:

_document.write_ ドキュメントストリームに書き込みます。閉じた(または読み込まれた)ドキュメントで _document.write_ を呼び出すと、ドキュメントをクリアする _document.open_ が自動的に呼び出されます。

- MDNからの引用

document.write() には2つのヘンチマン、 document.open() 、および document.close() があります。 HTMLドキュメントがロードされているとき、ドキュメントは「開いています」。 ドキュメントの読み込みが完了すると、ドキュメントは「閉じた」状態になります。document.write() を使用すると、この時点で(閉じた)HTML全体が消去されます文書化し、新しい(開いている)文書に置き換えます。これは、ウェブページがそれ自体を消去し、新しいページの書き込みをゼロから始めたことを意味します。

私は document.write() を使用すると、ブラウザのパフォーマンスも低下します(間違っている場合は修正してください)。


例:

この例では、ページがロードされた後、HTMLドキュメントafterに出力を書き込みます。 document.write() の「exterminate」ボタンを押すと、ドキュメント全体をクリアする邪悪な力に注意してください。

_I am an ordinary HTML page.  I am innocent, and purely for informational purposes. Please do not <input type="button" onclick="document.write('This HTML page has been succesfully exterminated.')" value="exterminate"/>
me!_

代替案:

  • _.innerHTML_これはすばらしい代替手段ですが、この属性はテキストを配置する要素に添付する必要があります。

例:document.getElementById('output1').innerHTML = 'Some text!';

  • .createTextNode()は、 W3C が推奨する代替手段です。

例:var para = document.createElement('p'); para.appendChild(document.createTextNode('Hello, '));

注:これは、パフォーマンスが多少低下することがわかっています(_.innerHTML_よりも遅い)。代わりに_.innerHTML_を使用することをお勧めします。


_.innerHTML_代替の例:

_I am an ordinary HTML page. 
I am innocent, and purely for informational purposes. 
Please do not 
<input type="button" onclick="document.getElementById('output1').innerHTML = 'There was an error exterminating this page. Please replace <code>.innerHTML</code> with <code>document.write()</code> to complete extermination.';" value="exterminate"/>
 me!
<p id="output1"></p>_
71
Drazzah

Document.writeをインプレースで置き換えるコードは次のとおりです。

document.write=function(s){
    var scripts = document.getElementsByTagName('script');
    var lastScript = scripts[scripts.length-1];
    lastScript.insertAdjacentHTML("beforebegin", s);
}
23

document.writeの使用は パフォーマンスの懸念 (同期DOMインジェクションと評価)のために非常に嫌われていますが、実際には1もありません。 :1代替document.writeを使用して、オンデマンドでスクリプトタグを挿入する場合。

これを行うことを避けるための多くの素晴らしい方法があります(たとえば、依存関係チェーンを管理する RequireJS のようなスクリプトローダー)、より侵襲的であるため、最もよく使用されますthroughoutサイト/アプリケーション。

9
James M. Greene

質問は、実際に何をしようとしているかによって異なります。

通常、document.writeを使用できますsomeElement.innerHTML以上、document.createElementsomeElement.appendChild

JQueryのようなライブラリを使用し、そこにある修正関数を使用することも検討できます。 http://api.jquery.com/category/manipulation/

7
Wolph

これはおそらく最も正しい、直接の置き換えです: insertAdjacentHTML

5

GetElementById()またはgetElementsByName()を使用して特定の要素にアクセスし、innerHTMLプロパティを使用してみてください。

<html>
    <body>
        <div id="myDiv1"></div>
        <div id="myDiv2"></div>
    </body>

    <script type="text/javascript">
        var myDiv1 = document.getElementById("myDiv1");
        var myDiv2 = document.getElementById("myDiv2");

        myDiv1.innerHTML = "<b>Content of 1st DIV</b>";
        myDiv2.innerHTML = "<i>Content of second DIV element</i>";
    </script>
</html>
4
user432219

insertAdjacentHTML メソッドと document.currentScript プロパティを組み合わせることができます。

ElementインターフェースのinsertAdjacentHTML()メソッドは、指定されたテキストをHTMLまたはXMLとして解析し、結果のノードをDOMツリーの指定された位置に挿入します

  • 'beforebegin':要素自体の前。
  • 'afterbegin':要素の内部、最初の子の前。
  • 'beforeend':最後の子の後の要素のすぐ内側。
  • 'afterend':要素自体の後。

Document.currentScriptプロパティは、現在スクリプトが処理されている<script>要素を返します。最適な位置はbeforebeginです-新しいHTMLは<script>自体の前に挿入されます。

<script>
  document.currentScript.insertAdjacentHTML(
    'beforebegin', 
    'this is the document.write alternative'
);
</script>
2
Sorin

_document.write_の問題が見当たりません。おそらくそうであるように、構造化データから要素を構築するためにonloadイベントが発生する前にそれを使用している場合、それは使用するのに適切なツールです。 insertAdjacentHTMLを使用したり、DOMの構築後にノードをDOMに明示的に追加したりしても、パフォーマンス上の利点はありません。 4つのモデムのバンクで24時間年中無休のサービスの着信モデムコールをスケジュールするために使用していた古いスクリプトを使用して、3つの異なる方法でテストしました。

終了するまでに、このスクリプトは3000を超えるDOMノード、主にテーブルセルを作成します。 VistaでFirefoxを実行している7歳のPCでは、この小さな運動は、ローカルの12kbソースファイルからの_document.write_と、約2000回再使用される3つの1px GIFを使用して2秒未満で完了します。ページは、イベントを処理する準備ができた、完全に形成された存在にポップします。

insertAdjacentHTMLの使用は、スクリプトが開いたままにする必要があるタグをブラウザが閉じ、最終的にマングルページを作成するために2倍を取るため、直接の代替ではありません。すべてのピースを文字列に書き込んでからinsertAdjacentHTMLに渡すとさらに時間がかかりますが、少なくともページは設計どおりになります。他のオプション(一度に1つのノードを手動でDOMを再構築するなど)はあまりにもばかげているので、そこには行きません。

時々_document.write_を使用することがあります。 JavaScriptの最も古いメソッドの1つであるという事実は、それに対する反論ではなく、賛成の点です-意図していたことを正確に実行し、当初から実行されている高度に最適化されたコードです。

代替のロード後のメソッドが利用可能であることを知ってうれしいですが、これらは完全に異なる目的のために意図されていることを理解する必要があります。つまり、DOMが作成され、メモリが割り当てられた後にDOMを変更します。ブラウザーが最初にDOMを作成するHTMLを記述することをスクリプトが意図している場合、これらのメソッドを使用することは本質的にリソース集約的です。

それを書いて、ブラウザとインタプリタに仕事をさせてください。それが彼らの目的です。

PS:onloadタグでbody paramを使用してテストしたところ、この時点でもドキュメントはopenおよびdocument.write()関数のままです。また、Firefoxの最新バージョンでは、さまざまな方法の間に認識できるパフォーマンスの違いはありません。もちろん、おそらく大量のキャッシングがハードウェア/ソフトウェアスタックのどこかで行われていますが、それが本当にポイントです-マシンに仕事をさせてください。ただし、安価なスマートフォンでは違いが出る場合があります。乾杯!

2
bebopalooblog