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);
}
すべての要素をループせずにそれを行う方法はありません。もちろん、それを行う関数を書くこともできます。
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);
私が思いつくことができた最高のものはこれでした:
const $coins = document.querySelectorAll('.coins')
[...$coins].forEach($coin => $coin.addEventListener('dragstart', handleDragStart));
これはES6の機能を使用しているため、まずトランスパイルするようにしてください。
実際にはisこれを行う方法ループなしがあります:
[].forEach.call(nodeList,function(e){e.addEventListener('click',callback,false)})
そして、この方法は私のワンライナーヘルパーライブラリの1つで使用されています nanoQuery 。
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))
最も簡単な例は、この機能を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);
});
});
[〜#〜] edit [〜#〜]:NodeList.prototype.forEachは2016年11月からFFに存在していることに注意してください。いいえIEサポートは
別のオプションは、Object.defineProperty
を使用してaddEventListener
にNodeList
を定義することだと思います。これにより、NodeListを単一のノードと同じように扱うことができます。
例として、ここに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;
}
});
別の解決策は、イベント委任を使用することです。 「.coins」のクローゼットの親にeventlistenerを追加し、コールバックでevent.targetを使用して、「coins」クラスの要素がクリックされたかどうかを確認します。
プロトタイピングを使用することもできます
NodeList.prototype.addEventListener = function (type, callback) {
this.forEach(function (node) {
node.addEventListener(type, callback);
});
};