以下のようなDOM構成、JavaScriptだとして、親要素でスクロールイベントが発火しませんでした。でも何故かDocumentオブジェクトで登録したらスクロールイベントが発火しました。その間の要素で発火されない。 1
結論、そういう仕様です。MDNに書いてありました。
スクロールイベントはバブリングフェーズでは受け取れないため、Documentオブジェクト間の要素は無視されます。1 親要素で無視されます。
どうしても親要素で発火したい、というのであれば addEventListener
の第3仮引数 userCapture
にtrueを指定し、キャプチャーフェーズで発火させます。バブリングフェーズやチャプチャーフェーズについてはQiitaで @hosomichi さんが記事を書いています。
以下で実際に挙動を確認出来ます。
こちらがスクロールイベント確認用。
https://murashi-sn.github.io/sample-javascript-api/event_propagation/02
こちらが比較のためのクリックイベント確認用。
https://murashi-sn.github.io/sample-javascript-api/event_propagation/01
<div id="parent">
<div id="child">SCROLL BAR</div>
<div>
document.querySelector('#child').addEventListener('scroll', function() {
console.log('child event called.'); // 呼ばれる
});
document.querySelector('#parent').addEventListener('scroll', function() {
console.log('parrent event called.'); // 呼ばれない
});
document.querySelector('#parent').addEventListener('scroll', function() {
console.log('parrent event called.'); // これなら呼ばれる
}, true);
document.addEventListener('scroll', function() {
console.log('document event called.'); // 呼ばれない
});
参考
- DOMイベントのキャプチャ/バブリングを整理する 〜 JSおくのほそ道 #017
- StackOverflow
- MDN web docs スクロールイベントについて
- MDN web docs useCapuereについて