Всем привет! Допустим есть код:
var btn = document.querySelectorAll('button');
btn[0].addEventListener('click', function() {
console.log(btn[0].textContent);
});
btn[1].addEventListener('click', function() {
console.log(btn[1].textContent);
});
btn[2].addEventListener('click', function() {
console.log(btn[2].textContent);
});
<body>
<button>click me</button>
<button>click my</button>
<button>click im</button>
</body>
Вопрос: Возможно ли написать более компактную запись: btn[i].addEventListener(..) (или что-то еще) чтобы не перечислять каждую по отдельности? Спасибо.
Возможно ли написать более компактную запись: btn[i].addEventListener(..)
Да, возможно, для этого надо использовать цикл for
var btn = document.querySelectorAll('button');
for(var i=0;i<btn.length;i++){
btn[i].addEventListener(...)
}
При этом, чтобы внутри обработчика обращаться к нужной кнопке достаточно использовать для этого this
console.log(this.textContent);
var btn = document.querySelectorAll('button');
for (var i = 0; i < btn.length; i++) {
btn[i].addEventListener('click', function() {
console.log(this.textContent);
});
}
<body>
<button>click me</button>
<button>click my</button>
<button>click im</button>
</body>
Во первых, querySelectorAll
возвращает коллекцию, которую можно перебрать:
document.querySelectorAll('button')
.forEach(function(btn) {
btn.addEventListener('click', function() {
console.log(btn.textContent);
})
});
<body>
<button>click me</button>
<button>click my</button>
<button>click im</button>
</body>
Во вторых, можно обойтись одним обработчиком событий:
document.addEventListener('click', function(e) {
if(!e.target.matches('button')) return;
console.log(e.target.textContent);
})
<body>
<button>click me</button>
<button>click my</button>
<button>click im</button>
</body>
Можно кнопки перебрать.
let btn = document.querySelectorAll('button');
btn.forEach(c => {
c.addEventListener('click', () => {
console.log(c.textContent)
})
})
<button>click me</button>
<button>click my</button>
<button>click im</button>
Взято из learn.javascript.ru.
Если есть много элементов, события на которых нужно обрабатывать похожим образом, то вместо того, чтобы назначать обработчик каждому – ставится один обработчик на их общего предка. Из него можно получить целевой элемент event.target, понять на каком именно потомке произошло событие и обработать его.
Хороший пример обработчика и для абсолютно разных действий.
<div id="menu">
<button data-action="save">Сохранить</button>
<button data-action="load">Загрузить</button>
<button data-action="search">Поиск</button>
</div>
<script>
function Menu(elem) {
this.save = function() {
alert( 'сохраняю' );
};
this.load = function() {
alert( 'загружаю' );
};
this.search = function() {
alert( 'ищу' );
};
var self = this;
elem.onclick = function(e) {
var target = e.target;
var action = target.getAttribute('data-action');
if (action) {
self[action]();
}
};
}
new Menu(menu);
</script>
про data атрибут тут
Возможно ли написать более компактную запись: btn[i].addEventListener(..)
Вполне, мне больше нравится через for-each, не смотря но то что это немного избыточно, по сравнению с обычным циклом по элементам NodeList:
Array.prototype.slice.call(document.querySelectorAll("button"))
.forEach(function(btn){
btn.addEventListener('click', function() {
console.log(btn.textContent)
});
});
<body>
<button>click me</button>
<button>click my</button>
<button>click im</button>
</body>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нужно спарсить инфу с сайтаПроблема в том, что он одностраничный (SPA)
Друзья, подскажите пожалуйста, почему в данном случае в obj3 свойству size присвоилось значение 40, а addheight осталась 50 по умолчанию в obj3, и как нужно...