どもです、manji6です。
node.jsみたいなサーバー側言語を触りたいなと思いつつ、ほとんどInterface系のJavaScript
しか触っていないのですが・・・
最近WebInterface系の実装をしていてサイ本を読み返してたらわかったことです。
「知ってるよボケ!」って言うJavaScriptマスターな方々には常識的な内容です。
JavaScriptでイベント定義をすると思うんですが、「そのイベント処理自体が重い」事ってありません?
例えば、ある要素を変更すると非同期通信をして、その戻り値を描画するみたいな。
分かりやすい事例で行くと、セレクトボックスの変更時に処理するとかですね。
JavaScriptでonclickなどのevent処理を高速に処理させる簡単な方法 sample1 – jsdo.it – share JavaScript, HTML5 and CSS
こういうのを実際に書いてみると分かるんですが、非同期通信が帰ってくるまでブラウザ自身の処理が
もたつく場合があります。特にこのセレクトボックスが曲者で「閉じる処理」が固まるんですね。
特にIE系のブラウザで顕著に発生します。
原理は簡単で、ClickやChangeイベントで定義した処理はブラウザ自身の処理よりも先に動きます。
そのイベント定義された処理が「完了」しないとブラウザ自身の処理は進まないということですね。
でも「ブラウザ自身の処理は先にやっていいからこっちが書いたJavaScript処理は先にやってよ!」
という場合は多々あると思います。例にあげたものもそうですが、別にセレクトボックスを閉じ
たりする処理をブロックする必要はなく、非同期通信の結果まで待つ必要はないです。
そういう場合は、「setTimeout()」を使うことで解決できます!
setTimeout()は指定した時間後に指定した関数を呼び出すタイマーとして使うのが定石ですが、
もう一つ重要な利点として「setTimeout()内で指定した関数は、必ず呼び出された処理が終わ
ってから実行されることが保証される」というところにあります。
まさに今回の事例ぴったりですね。
ということで改良したのがこちら。
何が違うって、change()内の処理全体をsetTimeout()の無名関数で括っただけです。
10msという微小数値をしておけばそこまで処理タイマーとしての所は無いと
思いますので、大丈夫かと。
気をつけなければいけないのはsetTimeout()の引数として渡す関数内におけるthisは
グローバル名前空間になってしまう所。うまく値をクロージャーで渡すなどして
おけば問題ありません。
コメントを残す