jQueryでのuseCaptureの扱い(addEventListenerの引数)
今、javascriptの勉強会用の資料を書いているのだが。
target.addEventListener(type, listener [, useCapture]);
のuseCaptureについて、
jQuery内でどう使われているか調べてみたら、
面白かったので、そのまとめ。
useCaptureとは?
addEventListenerを書く時の3番目のbooleanの引数。
ただ、この説明だと、よくわからない。
この説明が一番、分かり易かった。
要するに、
useCapture=false : 通常のイベントハンドラ
- バブリングフェーズで呼ばれる
- DOMの子から親にイベントが伝搬する
useCapture=trueのイベントハンドラ
- キャプチャフェーズで呼ばれる
- DOMの親から子にイベントが伝搬する
実際の所
useCapture=falseのままで良さそう。
- ブラウザ毎の動作違いを防ぐため(特にIE)
IEとuseCapture
IE9から
- addEventListenerに対応
IE8まで
attachEventを使わないといけない。
- キャプチャフェーズが無いっぽい(useCaptureが設定できない)
なので、useCapture=trueでIE以外のbrowserで動いても、
IE8以下で、異なる動作をしてしまう可能性がある。なので、false。
jQueryでどうなってるのか?
ここからが本題。
jQueryでどう扱われているのか、気になった。
jqueryでaddEventListenerをgrep
$ find src/ -type f -print | xargs grep addEventListener --color=auto src//core.js: document.addEventListener( "DOMContentLoaded", completed, false ); src//core.js: window.addEventListener( "load", completed, false ); src//event.js: // Only use addEventListener if the special events handler returns false src//event.js: if ( elem.addEventListener ) { src//event.js: elem.addEventListener( type, eventHandle, false ); src//event.js: document.addEventListener( orig, handler, true );
結論
殆ど、useCapture=false固定だった。(バブリングフェーズ)
例外的に、最後の1行だけ、useCapture=trueを固定で設定している箇所があった。
これは?
jQueryでuseCapture=true
// Create "bubbling" focus and blur events // Support: Firefox, Chrome, Safari if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0, handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); }; jQuery.event.special[ fix ] = { setup: function() { if ( attaches++ === 0 ) { document.addEventListener( orig, handler, true ); } }, teardown: function() { if ( --attaches === 0 ) { document.removeEventListener( orig, handler, true ); } } }; }); }
この固まりの、真ん中で、
- addEventListenerの第3引数(useCapture)が 「 true 」になっている。
focus / blurの時だけ、useCapture=trueにしてる?
focus blurイベントとjQuery
そもそもDOMでfocus / blurの時は、バブリング使うな。と書いてある。
この標準的な動きに合わせるために、
useCapture=trueにしているっぽい。
その他のイベントは?
上記のDOMのpage見ると、他にもbubbling:noと書いているイベントが2つある。
- load
- unload
これらは、多分、バブリングで困る事は無いから
(focusみたいにDOM触らないから)
わざわざ書いてないのかな?
IE8とjquery
確認していないけど、IE8だと、focusの動きが若干違うという事かな?
そもそも、IE8は、今のjquery2から捨てられてるしね。
おしまい。