前回の記事「JavaScript に関する 9 つの落とし穴とコメント」、ポイント 9 Focus Pocus で述べた問題を見てみましょう。元の作者はこれについて偏った理解を持っています。実際、これは IE だけの問題ではなく、既存の JavaScript エンジンのスレッド実装の問題です (スレッドについての概念はあまりありません。間違っている場合は、それを願っています)。読者の方が私にアドバイスをくれるかもしれません)。 1と2を見てみましょう。ソース コードを見ると、私たちのタスクは非常に単純であることがわかります。入力テキスト ボックスをドキュメントに追加し、フォーカスして選択するだけです。ここでそれぞれをクリックしてください。1 にはフォーカスして選択することはできませんが、2 にはフォーカスして選択できることがわかります。それらの違いは、
input.focus();
input.select();
の実行時に、遅延時間が 0 の追加の setTimeout 周辺関数があることです。 :
setTimeout(function(){
input.focus();
input.select();
}, 0);
JavaScript に従ってください: 決定版ガイド 5 番目 14.1発言:
実際には、setTimeout は、現在遅延されているイベントのイベント ハンドラーの実行を完了し、ドキュメントの現在の状態を更新した後、setTimeout 内に登録された関数を有効にするようにブラウザーに指示します。
実は、これは実行する必要のあるタスクのキューから飛び出すテクニックです。前の例に戻ると、JavaScript エンジンが onkeypress を実行する場合、複数のスレッドの同期実行がないため、新しく作成された要素の focus イベントと select イベントが存在しないため、これら 2 つのイベントを同時に処理することはできません。例 1 でわかるように、onkeypress の完了後、キューでは JavaScript エンジンがこれら 2 つのイベントを破棄しました。例 2 では、setTimeout によってタスクを特定のキューから新しいキューにジャンプできるため、期待どおりの結果が得られます。
これが遅延イベント 0 を使用した setTimeout の本当の目的です。ここでは、例 3 を見てみましょう。そのタスクは、入力されたテキストをリアルタイムで更新することです。たとえば、「a」と入力すると、プレビュー領域が常に 1 拍遅れることがわかります。プレビューエリアに は表示されません。 b を入力すると、静かに a が表示されます。実際には、プレビュー領域と入力ボックスを同期する方法があります。上記の方法で解決できるため、ここでは答えていません。