web-dev-qa-db-ja.com

クラスのJavaScriptクリックイベントリスナ

私は現在、クリックされたクラスの属性を取得するためにJavaScriptを書くことを試みています。これを正しく行うには、イベントリスナーを使用する必要があることを私は知っています。私のコードは次のとおりです。

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

classname.addEventListener('click', myFunction(), false);

クラスをクリックして属性を通知するたびに警告ボックスが表示されることを期待していましたが、残念ながらこれは機能しません。誰かが喜ばせることができますか?

- これはjQueryで簡単にできますが _それを使いたい

162
30secondstosam

これでうまくいくはずです。 getElementsByClassNameは、 アレイ 条件に一致する要素の配列風オブジェクト(編集参照)。

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

for (var i = 0; i < classname.length; i++) {
    classname[i].addEventListener('click', myFunction, false);
}

jQueryがあなたのためにループする部分をします、あなたは普通のJavaScriptでする必要があります。

ES6をサポートしている場合、最後の行を次のように置き換えることができます。

    Array.from(classname).forEach(function(element) {
      element.addEventListener('click', myFunction);
    });

注:古いブラウザ(IE6、IE7、IE8など)はgetElementsByClassNameをサポートしていないため、undefinedが返されます。


編集:修正

getElementsByClassNameは配列を返しませんが、ほとんどのHTMLCollection、またはNodeListは一部のブラウザです( Mozilla ref )。これらの型は両方とも配列に似ています(つまり、長さプロパティを持ち、オブジェクトはそのインデックスを介してアクセスできます)が、厳密には配列ではないか、配列から継承されません。 (Arrayに対して実行できる他のメソッドは、これらの型に対しては実行できません)

これを指摘してくれ、そして完全に理解するために私に掘ってもらってくれたユーザー@ Nemo に感謝します。

273
Anudeep Bulla

*これはターゲットクラスの子がイベントを引き起こすことができるように編集されました。詳細は答えの下を見てください。 *

項目が頻繁に追加および削除されるクラスにイベントリスナーを追加するための代替回答。これは、イベントがリスンしている子要素のセレクターを渡すことができるjQueryのon関数に触発されています。

var base = document.querySelector('#base'); // the container for the variable content
var selector = '.card'; // any css selector for children

base.addEventListener('click', function(event) {
  // find the closest parent of the event target that
  // matches the selector
  var closest = event.target.closest(selector);
  if (closest && base.contains(closest)) {
    // handle class event
  }
});

フィドル: https://jsfiddle.net/u6oje7af/94/

これはbase要素の子に対するクリックを監視し、クリックのターゲットがセレクタと一致する親を持つ場合、クラスイベントが処理されます。個々の要素にクリックリスナーを追加しなくても、要素を自由に追加および削除できます。このリスナーが追加された後に追加された要素であっても、これはそれらすべてをキャッチします。これはjQuery機能(私が想像するとやや類似している)のようです。

これは伝播するイベントによって異なります。そのため、他の場所でイベントをstopPropagationにしている場合、これは機能しない可能性があります。また、closest関数には、明らかにIEとの互換性の問題がいくつかあります(そうではありません)。

このようなアクションを繰り返しリスニングする必要がある場合は、これを関数にすることができます。

function addChildEventListener(base, eventName, selector, handler) {
  base.addEventListener(eventName, function(event) {
    var closest = event.target.closest(selector);
    if (closest && base.contains(closest)) {
      // passes the event to the handler and sets `this`
      // in the handler as the closest parent matching the
      // selector from the target element of the event
      handler.call(closest, event);
    }
  });
}

============================================
編集:この記事はもともとイベントターゲットのDOM要素にmatches関数を使用していましたが、これはイベントのターゲットを直接クラスのみに制限しました。代わりにclosest関数を使用するように更新され、目的のクラスの子のイベントでもイベントをトリガーできるようになりました。オリジナルのmatchesコードはオリジナルのフィドルにあります: https://jsfiddle.net/u6oje7af/23/

8
obermillerk

以下のコードを使うことができます。

document.body.addEventListener('click', function (evt) {
    if (evt.target.className === 'databox') {
        alert(this)
    }
}, false);
3
Rajat kumar