- ベストアンサー
addEventListener の第三引数の意味
- addEventListenerの第三引数の意味について、具体的な使い分けや適切な場合を教えてください。
- addEventListenerの第三引数は、ユーザがキャプチャを開始したいかどうかを示します。
- 一般的には、第三引数がtrueの場合はキャプチャフェーズで、falseの場合はバブリングフェーズでイベントが処理されます。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
バブリングするイベントタイプ(click、keydown) ・ルートノード → (キャプチャリングフェーズ)→ ターゲット → (バブリングフェーズ)→ ルートノード バブリングしないイベントタイプ(focus、load) ・ルートノード → (キャプチャリングフェーズ)→ ターゲット このように、バブリングしないイベントタイプであってもキャプチャリングフェーズは発生します。だから、 // activeElement をサポートしないブラウザ向け document.addEventListener('focus', function (e) { e.currenttarget.activeElement = e.target; }, true); のように、バブリングしない focus をルートノードで監視することも可能です。かつ、キャプチャリングという割り込みをルートノードで行うということは、あらゆるイベントリスナの前に実行されるという意味ですから、activeElement について整合性を崩すようなこともありません。 実のところ、click や keydown なんて「具体的な操作」イベントを監視せずとも、focus さえ監視すれば両方の代替になる、という場合がよくあります(廃止された DOMActivate の代替)。そんなとき、いちいち個々の要素で focus を監視するのでなく、キャプチャリングを使ってルートノードで一括監視できます。 --- キャプチャリングはもともと Netscape に由来し、IE では ver. 9 になるまでありませんでした。IE には focusin というバブリングするイベントタイプがあり、結局それが DOM3-Events に収録されています。 ブラウザの DOM 文書木というのは、誰がどう弄るか分かりません。ならば、イベントの発生源を直接監視するのでなく、発生源からできるだけ遠くから監視するのが安全です。そうすれば、自然とイベントオブジェクトに情報を問い合わせる形になるはずです。
その他の回答 (3)
- Chaire
- ベストアンサー率60% (79/130)
多用するか否かで言えば、キャプチャリングは多用するものではないと思います。『JavaScript: The Good Parts』の著者 D. Crockford に至っては「バブリングは大いに使え、しかしキャプチャリングは避けろ」とまで言っています。確かに、addEventListener() の通常用途としてはその方が良いでしょう。 ところで、IE の独自拡張に element.setCapture() というのがあります。これは、ブラウザ外も含めてあらゆる場所で起きたイベントを、一度だけ「element で起きたもの」として渡します。「どこをクリックしても、element をクリックしたことになる」わけです。全画面で警告を出した後、どこかをクリックすれば元に戻る、みたいな用途に使えますね。 今のところ、IE 以外でそのようなブラウザ外イベントを拾うことはできません。しかしブラウザ内であれば、キャプチャリングを使うことでターゲットより先にイベントを拾うことができます。つまり、モーダルウィンドウのように「一定の範囲以外は一時的に入力を受け付けない」状態にできるわけです。 仕組みは違えど、名前(と目的)が同じということで。
お礼
setCapture試してみました。 ちょっとびっくりしました。面白いですね。 いつか使ってみたいと思います。 また参考になりました。ありがとうございました。
- dscripty
- ベストアンサー率51% (166/325)
[ANo.2] さんの回答をもとに、具体的なケースを考えてみたよ! 例えば、 「文字列を選択して、右クリックをすると独自のメニューが表示される。」 という機能を実装するときに、 一つ一つの要素を Listening するのではなくて、 ルート要素を true で Listening する。 というイメージ。
お礼
試してみました。 右クリックはcontextmenuだと思うのですが、これはclickと同じようでfalseでも親で観測できました。つまり親だけで観測しようとするならばtrueでもfalseでも変わりませんでした。 一方focusではtrueにしなければ親で観測できませんでした。 結論を言うとイベントを親で観測したいときに、falseでうまくいかなかったらtureにしてみろ、ということかなと思いました。(曲解かもしれませんが) 試すきっかけになりました。ありがとうございました。
- dscripty
- ベストアンサー率51% (166/325)
JavaScript ソースを全部自分で編集できる立場にあれば、あまり使い道はないとおもう。。。 他の人のウェブページの動きをユーザスクリプトで手を加えたいときにつかうのかな? http://ja.wikipedia.org/wiki/Greasemonkey ケースその1 子要素が onclick を Listen しているけれど、子要素の listner を呼ばせたくないとき。 子要素の listner が呼ばれないようにするためには、 .removeListner() で listener を指定ればよいけれど、一般的に、ユーザスクリプトから listner を調べる方法がないから使えない。 なので、親要素の onclick を true で捕捉して、return false でぬければ、子要素の listener が呼ばれることを回避できる。 ケースその2 子要素が onclick を Listen しているけれど、子要素の listner が呼ばれる前に別の処理をしたいとき。 親要素の onclick を true で捕捉して、別の処理を済ませたら return true でぬければ、その後、子要素の listener が呼ばれる。 ケースその3 子要素が onclick を Listen していて、listner が return true で抜ける場合に、その後に別の処理をしたいとき。 親要素の onclick を false で捕捉すれば、子要素の listner が return true でぬければ、親要素の listner が呼ばれるから別の処理を実行できる。 。。。ような気がする。
お礼
なるほど。ユーザスクリプトで独自のイベントを追加したいときには使える場面があるかもしれませんね。(ものすごく限定された例ですが) とにかくほとんど使い道はなくあまり気にしなくてもいい事ということですかね。 参考になりました。ありがとうございました。
お礼
少し難しいかったです…。 イベントの種類によって、バブリングしないイベントもあるのですね。知りませんでした。 そのようなイベントでかつ親で観測したい場合には、なるほど確かにtrueにする必要がありますね。 参考になりました。ありがとうございました。