以下のコードでid=koreにクリックイベントをセットします。
しかし、ボタンに表示されている画像の部分をクリックするとコールバックのe.targetがbuttonでなくimgになってしまいます。
e.currentTargetを使えばbutton要素が取得出来るのは知っているのですが、button要素を取得する方法ではなくimg要素でイベントが発生しないようにする方法を知りたいです。
ボタンの中の画像をクリックしてe.targetがimgの時と、ボタンの中の画像が無い所をクリックしてe.targetがbuttonの時で、画面の表示が微妙に異なり、e.targetがbuttonの時の表示に固定したいのです。
createEvent→initMouseEvent でイベントを作成しても挙動が違いました。
js
1document.querySelector("#kore").addEventListener("click",function(e){ 2 //e.target or e.currentTarget 3});
html
1<button id="kore"> 2 <img src="xxx"> 3</button> 4```、
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
バブリングフェーズ、キャプチャリングフェーズを強制終了
イベントの発火を防止するのは原理的に不可能だと思います。
バブリングを停止することで上位要素のバブリングフェーズにおいてイベントが発火していないかのように見せかける事は可能です。
JavaScript
1'use strict'; 2document.querySelector('#kore *').addEventListener('click', function (event) { 3 event.preventDefault(); // デフォルトアクションを抑止 4 event.stopImmediatePropagation(); // バブリングを停止 5}, true); 6 7document.getElementById('kore').addEventListener('click', function (event) { // // #kore のみ発火する 8 console.log(event.type, 'bubbling-phase', '/ target = #' + event.target.id + ' / currentTarget = #' + event.currentTarget.id); 9}, false); 10 11document.getElementById('kore').addEventListener('click', function (event) { // // #kore 以外も発火する 12 console.log(event.type, 'capturing-phase', '/ target = #' + event.target.id + ' / currentTarget = #' + event.currentTarget.id); 13}, true); 14 15addEventListener('click', function (event) { // #kore 以外も発火する 16 console.log(event.type, 'capturing-phase', '/ target = #' + event.target.id + ' / currentTarget = window'); 17}, true);
キャプチャリングフェーズまで対応するなら最上位ノードである window.addEventListener
を監視するしかありません。
JavaScript
1'use strict'; 2addEventListener('click', function (event) { // #kore 以外も発火する 3 console.log(event.type, 'capturing-phase', '/ target = #' + event.target.id + ' / currentTarget = window'); 4}, true); 5 6addEventListener('click', function (event) { 7 for (var target = event.target, i = 0, elements = event.currentTarget.document.querySelectorAll('#kore *'), l = elements.length; i < l; ++i) { 8 if (target === elements[i]) { 9 event.preventDefault(); // デフォルトアクションを抑止 10 event.stopImmediatePropagation(); // キャプチャリングフェーズを強制終了 11 return; 12 } 13 } 14}, true); 15 16document.getElementById('kore').addEventListener('click', function (event) { // #kore のみ発火する 17 console.log(event.type, 'bubbling-phase', '/ target = #' + event.target.id + ' / currentTarget = #' + event.currentTarget.id); 18}, false); 19 20document.getElementById('kore').addEventListener('click', function (event) { // #kore のみ発火する 21 console.log(event.type, 'capturing-phase', '/ target = #' + event.target.id + ' / currentTarget = #' + event.currentTarget.id); 22}, true); 23 24addEventListener('click', function (event) { // #kore のみ発火する 25 console.log(event.type, 'capturing-phase', '/ target = #' + event.target.id + ' / currentTarget = window'); 26}, true);
当然ながら event.stopImmediatePropagation()
実行前のリスナーは無効化できませんので、event.stopImmediatePropagation()
は一番初めに実行する必要があります。
event.target で分岐処理
Fushihara さんが期待する動作ではないかもしれませんが、個人的には次のように書きます。
JavaScript
1document.getElementById('kore').addEventListener('click', function (event) { 2 if (event.target !== event.currentTarget) { // event.target が #kore でないなら強制終了 3 return; 4 } 5 6 console.log(event.type, '#' + event.target.id); 7}, false);
Re: Fushihara さん
投稿2016/09/14 03:27
編集2016/09/14 04:34総合スコア18162
0
イベント自体を止めることは無理ですが、無視することは出来ます。
HTML
1<div id="kore"> 2 <img src="https://placehold.jp/8/cc9999/993333/50x30.png"> 3 てきすと 4</div> 5```として 6```JavaScript 7document.querySelector( '#kore' ).addEventListener( 'click', function( e ) { 8// if ( e.target.tagName === 'img' ) { // 修正前(コメント欄参照) 9 if ( e.target.tagName === 'IMG' ) { // 修正後 10 e.stopPropagation(); 11 return; 12 } 13 /* do something. */ 14}, false ); 15```か 16```JavaScript 17document.querySelector( '#kore img' ).addEventListener( 'click', function( e ) { 18 e.stopPropagation(); 19}, false ); 20document.querySelector( '#kore' ).addEventListener( 'click', function( e ) { 21 /* do something. */ 22} );
ではどうでしょう。
※ buttonタグの場合上記記述では使え無いと思います。
投稿2016/09/14 03:57
編集2016/09/14 04:28総合スコア69407
0
querySelector()はあまり使ったことがないですが、ブラウザによって挙動が違うようですね
いずれ仕様が統一されるような気もしますが、今回の件に関していえば場当たり的ですが
子要素を掴んでいるのであれば親に遡ればよいのではないでしょうか?
javascript
1function(e){ 2 var t=e.target; 3 while(t){ 4 if(t.nodeName=="BUTTON") break; 5 t=t.parentNode; 6 } 7 console.log(t.nodeName); 8}); 9
投稿2016/09/14 03:24
総合スコア114806
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。