クリックイベントで要素の中に含まれる特定の要素を除外したいときの対処法【JavaScript】

JavaScript

JavaScriptでclickイベントを検知するには要素.addEventListener('click', function(){…を使いますね。ですが要素の中にある特定の要素では発火して欲しくない場合が時々あります。

たとえば

A
B

上のようなDOM構造があり、Aにクリックイベントを指定しているけど、Bでは発火しないようにしたいときです。Aのクリックイベントは下記のように記述します。

let mainElement = document.getElementById('A');

mainElement.addEventListener('click', function(){
  // Aをクリックしたいときの処理
});

AはクリックしたいけどBは反応しないで欲しい時

しかしこれだけではBのエリアをクリックしたときもAをクリックしたと認識され、イベントが発火してしまいます。

そこでスクリプトを少し修正し、下記のようにします。

let mainElement = document.getElementById('A');

mainElement.addEventListener('click', function(e){ // (1)
  if(e.target.id == 'B'){  // (2)
    console.log('Bがクリックされました');
    return false; // (3)
  }
  // Aをクリックしたいときの処理
    console.log('Aがクリックされました');
});

もしくは(2)を先祖要素を取得するclosest()を使って次のように書いてもOKです。実際に実装する際に使い分けてください。

let mainElement = document.getElementById('A');

mainElement.addEventListener('click', function(e){ // (1)
  if(e.target.closest('#B')){  // (2)
    console.log('Bがクリックされました');
    return false; // (3)
  }
  // Aをクリックしたいときの処理
    console.log('Aがクリックされました');
});

少し解説しておくと、
(1)は、clickイベントのイベントオブジェクトをプログラムで利用するためにfunction(e)としています。(2)はe.targetでclickイベントが発火した要素を取得し、そのidがBだったら処理をする分岐を追加します。(3)はそれ以上処理が進まないようにreturn: false;でイベントを中止しています。

特に難しいことはありませんが、もしイベントオブジェクトがよくわからない場合にはhttps://developer.mozilla.org/ja/docs/Web/API/Eventを参考にしてみてください。

jQueryで記述する場合

jQueryで同様の記述をしてもきちんと動作します。

let $mainElement = $('#A');

$mainElement.on('click', function(e){
  if(e.target.id == 'B'){
    console.log('Bがクリックされました');
    return false;
  }
  // Aをクリックしたいときの処理
    console.log('Aがクリックされました');
});

もちろんJavaScriptと同じくclosest()を使っても大丈夫です。

サンプル

以下のサンプルはD以外のCのエリアをクリックするとalert()でダイアログが表示されます。

C
D

以上、是非お役立てください。

タイトルとURLをコピーしました