9

これを Chrome (ver 2) で実行すると文字列が返されませんが、Firefox (ver 3) では機能します。どうしてこれなの?

<html>
<head>
<script type="text/javascript">
function disp_prompt() {
    var name=prompt("Please enter your name","Harry Potter");
    if (name!=null && name!="") {
        document.write("Hello " + name + "! How are you today?");
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>
4

4 に答える 4

32

ドキュメントにコンテンツを追加するにはdocument.write()、<script> ブロックの解析段階でのみ呼び出す必要があります。

イベントハンドラーなど、そのコンテキスト外で実行される場所への呼び出しがある場合document.write、解析は行われないため、その文字列はどこにも'foo'行きません。

元の JavaScript リファレンスによると、次のようになります。

イベント ハンドラーは元のドキュメントが閉じられた後に実行されるため、イベント ハンドラーで document.open メソッドを明示的に発行しない場合、write メソッドは暗黙的に mimeType text/html の新しいドキュメントを開きます。

つまり、あなたが間違いを犯し、次のことを行うつもりであると想定しています。

document.open('text/html');
document.write(html);

これにより、ドキュメント全体が新しいコンテンツに置き換えられます。次の呼び出しでそれを終了しなかったため、次のことにも気付くでしょう。

document.close();

...Firefox では、「読み込み中」のスロバーはまだアニメーション化されており、ドキュメントにさらにコンテンツが書き込まれることを期待しています (しかし、決して来ません)。

この場合、document.write()文字列を ing しています:

Hello bobince! How are you today?

これは明らかに有効な HTML ドキュメントではありません。Chrome (および同じように動作する Safari) は、それを HTML ドキュメントとして解析しようとしますが、許可されていないドキュメント要素 (<html>) の外側にある空白以外のテキスト コンテンツであるため、失敗します。名前の入力にいくつかのタグを入れると、次のようになります。

Hello <em>bobince</em>! How are you today?

<em> 要素の外側にあるものはすべて破棄されます。Firefox と IE は、「要素外のテキストを修正する」壊れた HTML ルールを適用してユーザーを救おうとしていますが、Chrome はそうではありません。

新しいドキュメントが必要な場合document.write()は、それが完全なドキュメントであることを確認する必要があります。

<html><head><title>Greetings</title><body><p>Hello bobince! How are you today?</p></body></html>

または、document.write()テキスト文字列が必要な場合は、理論的には次のように呼び出す必要があります。

document.open('text/plain');

write() の前に。ただし、mimetype パラメータは Chrome や Safari ではサポートされていないことに注意してください。彼らはあなたが書いたものを常に HTML として扱います。

いずれにせよ、おそらくこのメソッドを使用したくないでしょう。既存のページに追加 (または変更) する場合は、通常、ステータス出力 div にテキストを設定するか、innerHTML を使用して本文コンテンツを置き換えるなど、DOM メソッドを使用する必要があります。

document.write()いくつかの場所で必要になりますが (特に、新しいウィンドウまたはフレームを最初から作成する場合)、それ以外の場合は一般的に間違っているため、疑いを持って表示する必要があります。

于 2009-04-18T02:56:00.827 に答える
9

document.write を使用しないでください。のようなものに変更すると

if (name != null && name != "") {
    document.getElementById('foo').innerHTML = "Hello " + name + "! How are you today?";
}

<body>
<input ...

<div id='foo'> </div>
</body>

document.write にはかなり奇妙な動作があります。テキストはどこに書かれていると思いますか?

于 2009-04-17T22:26:21.893 に答える
2

書き込み呼び出しにいくつかの段落タグを追加するだけです。

<html>
<head>
<script type="text/javascript">

function disp_prompt() {
    var name = window.prompt("Please enter your name", "Harry Potter");
    if (name) {
        window.document.write("<p>Hello " + name + "! How are you today?<\/p>");
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>
于 2009-04-17T23:37:14.533 に答える
0

document.write()パーティーにはちょっと遅れましたが、Chrome DevTools でリンクに関する違反が見られました。面白く読んだことは言うまでもありません。

何のことですか?

Chrome v55 以降、Chrome はdocument.write()非常に限られた状況下でブロックを開始します。ここでそれについて読むことができます:

https://developers.google.com/web/updates/2016/08/removing-document-write

これは、2G セルラー接続を使用しているユーザー、および場合によっては低速な他のタイプの接続を使用しているユーザーに対してのみ有効になります。問題の記事の抜粋は次のとおりです。

このデータを念頭に置いて、バージョン 55 以降の Chrome は、Chrome での document.write() の処理方法を変更することで、この既知の悪いパターンを検出すると、すべてのユーザーに代わって介入します (Chrome ステータスを参照)。具体的には、次の条件がすべて満たされている場合、Chrome は document.write() によって挿入された要素を実行しません。

  1. ユーザーの接続速度が遅い (特にユーザーが 2G を使用している場合)。(将来的には、低速の 3G や低速の WiFi など、低速の接続を使用している他のユーザーにも変更が適用される可能性があります。)
  2. document.write() は最上位ドキュメントにあります。メイン ページのレンダリングをブロックしないため、介入は iframe 内の document.written スクリプトには適用されません。
  3. document.write() 内のスクリプトはパーサー ブロッキングです。「async」または「defer」属性を持つスクリプトは引き続き実行されます。
  4. スクリプトは同じサイトでホストされていません。つまり、eTLD+1 が一致するスクリプト (たとえば、www.example.orgに挿入された js.example.org でホストされているスクリプト) には、Chrome は介入しません。
  5. スクリプトは、ブラウザの HTTP キャッシュにまだありません。キャッシュ内のスクリプトはネットワーク遅延を発生させず、引き続き実行されます。
  6. ページのリクエストはリロードではありません。ユーザーがリロードをトリガーした場合、Chrome は介入せず、通常どおりページを実行します。

サードパーティのスニペットは、document.write() を使用してスクリプトをロードすることがあります。幸いなことに、ほとんどのサード パーティは、ページ上の残りのコンテンツの表示をブロックすることなく、サード パーティのスクリプトを読み込むことができる非同期読み込みの代替手段を提供しています。

したがって、document.write()6 つの基準をすべて満たす場合、Chrome はそれをブロックします。メッセージが発生すると、DevTools でメッセージを確認できるはずです。

OPの質問

OPの質問に対処するには、使用document.write()するには最初に使用する必要がありますdocument.open("text/html")。ドキュメントへの書き込みが完了したら、 を使用する必要がありますdocument.close()。プレーンテキストを書くだけなら、document.open("text/plain"). ただし、最近、Chrome が MIME タイプを無視し、text/html を強制することをどこかで読みました。

<html>
<head>
<script type="text/javascript">
function disp_prompt() {
    var name=prompt("Please enter your name","Harry Potter");
    if (name!=null && name!="") {
        document.open("text/plain");
        document.write("Hello " + name + "! How are you today?");
        document.close();
    }
}
</script>
</head>
<body>

<input type="button" onclick="disp_prompt()" value="Display a prompt box" />

</body>
</html>

- また -

次のように、適切な HTML を含めるように記述したテキストを変更できます。

document.write('<html><head></head><body>Hello ' + name + '! How are you today?</body></html>');

すべての場合にdocument.open()andを追加することを忘れないでください。document.close()

于 2021-07-16T14:57:41.677 に答える