Posted at

addEventListener の第3引数が拡張されてるという話

More than 1 year has passed since last update.

Webアプリケーションのお話です。

イベントハンドラを登録する addEventListener メソッドの引数は以下の形で覚えている人が大半だと思う。

element.addEventListener('click', myClickHandler, useCapture);

新しい Web 標準ではこういった形に拡張されているよ、という話。

element.addEventListener('click', myClickHandler, {

once: true,
passive: true,
capture: true
});


参考記事

https://developers.google.com/web/updates/2016/10/addeventlistener-once


EventListenerOptions

これまでの第3引数 useCaptureboolean 型をとり、イベントハンドラがキャプチャフェーズ or バブリングフェーズのどちらで処理されるかを制御するものだった。

この第3引数が Object 型も受け付けるようになり、現状、それぞれ boolean 型で once , passive , capture パラメータをとる。


once

true でイベントハンドラが1度だけ処理される。

例えば Windowload イベントハンドラは通常1度だけ実行される。イベントハンドラおよびそのスコープ変数はイベントハンドラ登録されている限り参照を保持するのでガベージコレクションの対象ではなく、こういったイベントハンドラはメモリの無駄となる。イベントハンドラ内で removeEventListener を記述するよりも容易にガベージコレクションのケアができるよという機能。


passive

true でこのイベントハンドラが Passive event であることをブラウザに伝える。

イベントハンドラは event.preventDefault() でブラウザのスクロールを抑止する可能性があるため、ブラウザはイベントハンドラの処理が終了するまでスクロールを開始することができず、その遅延はユーザー操作を阻害する。Passive event はブラウザのスクロールを抑止しないということで、このフラグが立ったイベントハンドラではブラウザは処理の完了を待つ必要がなくなり、ユーザー操作の阻害を回避することができる。

どの程度ユーザー操作が改善されるかは以下記事内の動画が参考になる。

https://developers.google.com/web/updates/2016/06/passive-event-listeners


capture

これまでの useCapture と同様、イベントハンドラがキャプチャフェーズ or バブリングフェーズのどちらで処理されるかを制御する。


これまで通り true|false を指定したらどうなるか?

boolean 型が来た場合は互換性が保持されているので、キャプチャフェーズ or バブリングフェーズの制御となる。


対応バージョン



  • passive


    • Chrome 51+

    • Firefox 49+

    • Safari's technology preview 7+




  • once


    • Chrome 55+

    • Firefox 50+

    • Safari's technology preview 7+



MicrosoftEdge は EventListenerOptions の Issue が Open だった(2016/11/17時点)。