jsタイマーsetTimeoutに深く入る
4723 ワード
ブラウザ内部のほとんどの動作は、非同期的にイベントを生成し、
まず、
非同期事件
前に述べたように、ほとんどのイベントは非同期です.トリガが発生したら、コールバック関数をイベントキューに追加します.ブラウザは、キューの検査やイベントの処理、実行関数などの内部回路を提供しています.詳細は前のブログを参照してください.
実際には、多くの相互作用と活動は、イベントを通じて循環しなければならない.
事件が重なる
いくつかの場合、複数のイベントが同じ時間にイベントキューに追加されます.
例えば、
set Timeout(func,0)奇巧淫技
このコードは私のブラウザで実行された結果は以下の通りです.
現地の
上記のテストは、単に
したがって、
奇巧淫技の一つ:模擬ブラウザのイベント捕獲
ご存知のように、ブラウザのDOMイベントはバブル方式を採用しています.個々のブラウザだけがイベントのキャプチャをサポートしています.実際の開発過程ではイベントトラッピングを必要とする需要があるかもしれませんが、親要素のトリガ後にサブ要素のイベントがトリガされます.各ブラウザに対応するためには、イベントキャプチャは使用できません.
奇巧淫技の二:ブラウザをより良い仕事にする
ほとんどの場合、ブラウザのデフォルトの行動の前に事件を処理することができますが、時々私たちはいつもの考えに沿って行動します.例えば次の例です.
次の入力がない場合、テキストボックスの小文字は永遠に大文字に変換されません.Whyなぜなら、ブラウザは
たぶんいいと思いますが、よく観察すれば問題が分かります.
閉店時に
上の二つのケースは氷山の一角だけです.そして、合理的に
JavaScript
のキューに追加され、次いでJavaScript
によってスケジュール実行される.したがって、ブラウザの多くのイベントは、JavaScript
と結合されているが、内部的な制約もある.まず、
JavaScript
は単一スレッドであると非常に決定しました.ブラウザにとっては、フォームの一つはJavaScript
だけです.他の行為は、例えば、レンダリング、ダウンロードなどは、個々のスレッドによって管理され、異なる優先度を有する.非同期事件
前に述べたように、ほとんどのイベントは非同期です.トリガが発生したら、コールバック関数をイベントキューに追加します.ブラウザは、キューの検査やイベントの処理、実行関数などの内部回路を提供しています.詳細は前のブログを参照してください.
Event Loop
およびsetTimeout
もまた、イベントキューに実行すべき関数を追加するものである.実際には、多くの相互作用と活動は、イベントを通じて循環しなければならない.
事件が重なる
いくつかの場合、複数のイベントが同じ時間にイベントキューに追加されます.
例えば、
setInterval
イベントは、2つの追加的なイベントを生成する.click
とmousedown
.mouseup
およびmouseup
イベントは、同時にイベントキューに追加される.click
イベントは、他のイベントと重複する可能性が高い:mousedown
.set Timeout(func,0)奇巧淫技
focus
についての誤解をもう一度説明すると、現在のクロック期間にキューが空きがある場合、直ちにこのタイマーを実行して、コールバック関数をイベントキューに追加する.その後、次のクロック周期を待って、このコールバック関数を実行します.下のテストを見に来てください.このコードは私のブラウザで実行された結果は以下の通りです.
現地の
0ms
環境で実行した結果は以下の通りです.上記のテストは、単に
Nodejs
のタイミングタスクを説明するためのコールバック関数の実行時間が遅延されています.いわゆる即時実行ではありません.したがって、
setTimeout(func, 0)
を用いて、イベントのオーバーラップによって生じる負の効果を解決し、実行順序を修正することができる.奇巧淫技の一つ:模擬ブラウザのイベント捕獲
ご存知のように、ブラウザのDOMイベントはバブル方式を採用しています.個々のブラウザだけがイベントのキャプチャをサポートしています.実際の開発過程ではイベントトラッピングを必要とする需要があるかもしれませんが、親要素のトリガ後にサブ要素のイベントがトリガされます.各ブラウザに対応するためには、イベントキャプチャは使用できません.
setTimeout(func, 0)
はこの時に喜んで手伝います."button" value="click" id="cbtn">
<div id="result"></div>
<script type="text/javascript"> var cbtn = document.getElementById('cbtn') , result = document.getElementById('result'); cbtn.onclick = function(e) { setTimeout(function() { result.innerHTML += 'input click, '; }, 0); }; document.body.onclick = function(e) { result.innerHTML += 'body click -> '; }; </script>
クリックして運行効果を確認します.奇巧淫技の二:ブラウザをより良い仕事にする
ほとんどの場合、ブラウザのデフォルトの行動の前に事件を処理することができますが、時々私たちはいつもの考えに沿って行動します.例えば次の例です.
"text" id="wordInput">
<script type="text/javascript"> var wordInput = document.getElementById('wordInput'); wordInput.onkeypress = function(e) { this.value = this.value.toUpperCase(); }; </script>
簡単な必要があります.文字を入力するごとに、大文字に変換します.でも上のコードは全く指示通りにしていません.信じないなら試してみてください.次の入力がない場合、テキストボックスの小文字は永遠に大文字に変換されません.Whyなぜなら、ブラウザは
setTimeout(func, 0)
イベントを処理する時、私たちが入力した値をテキストボックスに追加していないからです.そして、他のイベントをハンドルに変えてから処理しましょう.キーを押した時はまだ値がないので、キーを押してから処理します."text" id="wordInput">
<script type="text/javascript"> var wordInput = document.getElementById('wordInput'); wordInput.onkeyup = function(e) { this.value = this.value.toUpperCase(); }; </script>
運転してみましょうたぶんいいと思いますが、よく観察すれば問題が分かります.
keypress
イベントのトリガ時、テキストボックスはすでに完全な値を備えていますが、最初は小文字の値で、キーが完全に解放されてから大文字になります.これは科学ではないです.これは醜いです.閉店時に
keyup
を放出しました."text" id="wordInput">
<script type="text/javascript"> var wordInput = document.getElementById('wordInput'); wordInput.onkeypress = function(e) { var self = this; setTimeout(function() { self.value = self.value.toUpperCase(); }, 0); }; </script>
もう完璧ですsetTimeout(func, 0)
イベントのトリガ時に、大文字に変換された操作をイベントキューに追加し、続いてブラウザに入力された値を追加し、その後、ゼロに近い遅延で私たちの変換大文字操作関数を実行します.上の二つのケースは氷山の一角だけです.そして、合理的に
keypress
を利用して、明日はもっとすばらしいです.