36

NodeListはaddEventListenerをサポートしていますか。そうでない場合は、NodeListのすべてのノードにEventListenerを追加するための最良の方法は何ですか。現在、以下に示すようにコードスニペットを使用していますが、これを行うためのより良い方法はありますか。

var ar_coins = document.getElementsByClassName('coins');
for(var xx=0;xx < ar_coins.length;xx++)
{
        ar_coins.item(xx).addEventListener('dragstart',handleDragStart,false);
}
4

8 に答える 8

46

すべての要素をループせずにそれを行う方法はありません。もちろん、それを実行する関数を作成することもできます。

function addEventListenerList(list, event, fn) {
    for (var i = 0, len = list.length; i < len; i++) {
        list[i].addEventListener(event, fn, false);
    }
}

var ar_coins = document.getElementsByClassName('coins');
addEventListenerList(ar_coins, 'dragstart', handleDragStart); 

またはより専門的なバージョン:

function addEventListenerByClass(className, event, fn) {
    var list = document.getElementsByClassName(className);
    for (var i = 0, len = list.length; i < len; i++) {
        list[i].addEventListener(event, fn, false);
    }
}

addEventListenerByClass('coins', 'dragstart', handleDragStart); 

また、jQueryについては質問していませんが、これはjQueryが特に得意とする種類のものです。

$('.coins').on('dragstart', handleDragStart);
于 2012-09-11T03:44:53.303 に答える
22

私が思いついた最高のものはこれでした:

const $coins = document.querySelectorAll('.coins')
$coins.forEach($coin => $coin.addEventListener('dragstart', handleDragStart));

これはES6機能を使用しているため、最初にトランスパイルしてください。

于 2015-11-03T05:55:23.207 に答える
12

実際に、ループなしでこれを行う方法があります。

[].forEach.call(nodeList,function(e){e.addEventListener('click',callback,false)})

そして、この方法は、私のワンライナーヘルパーライブラリの1つであるnanoQueryで使用されています。

于 2013-01-31T12:53:40.667 に答える
7

最も簡単な例は、この機能をに追加することですNodeList

NodeList.prototype.addEventListener = function (event_name, callback, useCapture)
{
    for (var i = 0; i < this.length; i++)
    {
      this[i].addEventListener(event_name, callback, useCapture);
    }
};

今、あなたはすることができます:

document.querySelectorAll(".my-button").addEventListener("click", function ()
{
    alert("Hi");
});

同じように、あなたはforEachループを行うことができます

NodeList.prototype.forEach = function (callback)
{
    for (var i = 0; i < this.length; i++)
    {
      callback(this[i], i);
    }
};

使用:

document.querySelectorAll(".buttons").forEach(function (element, id)
{
    input.addEventListener("change", function ()
    {
        alert("button: " + id);
    });
});

編集:NodeList.prototype.forEachは2016年11月からFFに存在していることに注意してください。IEはサポートされていません

于 2016-04-12T09:20:17.840 に答える
6

es6では、Array.fromを使用して、nodelistから配列を実行できます。

ar_coins = document.getElementsByClassName('coins');
Array
 .from(ar_coins)
 .forEach(addEvent)

function addEvent(element) {
  element.addEventListener('click', callback)
}

または単に矢印関数を使用します

Array
  .from(ar_coins)
  .forEach(element => element.addEventListener('click', callback))
于 2016-12-07T13:35:01.560 に答える
2

別のオプションは、の使用を定義addEventListenerすることだと思います。そうすれば、NodeListを単一のノードと同じように扱うことができます。NodeListObject.defineProperty

例として、ここでjsfiddleを作成しました:http://jsfiddle.net/2LQbe/

重要なポイントはこれです:

Object.defineProperty(NodeList.prototype, "addEventListener", {
    value: function (event, callback, useCapture) {
        useCapture = ( !! useCapture) | false;
        for (var i = 0; i < this.length; ++i) {
            if (this[i] instanceof Node) {
                this[i].addEventListener(event, callback, useCapture);
            }
        }
        return this;
    }
});
于 2014-02-01T13:03:00.927 に答える
2

別の解決策は、イベント委任を使用することです。「.coins」のクローゼットの親にeventlistenerを追加し、コールバックでevent.targetを使用して、クリックがクラス「coins」の要素に実際にあったかどうかを確認します。

于 2018-12-31T19:08:55.047 に答える
0

プロトタイピングを使用することもできます

NodeList.prototype.addEventListener = function (type, callback) {
    this.forEach(function (node) {
        node.addEventListener(type, callback);
    });
};
于 2018-12-14T10:00:49.637 に答える