Добавление прослушивателя событий клика к элементам с одинаковым классом
У меня есть представление списка для удаления идентификатора. Я хотел бы добавить слушателя ко всем элементам с определенным классом и сделать предупреждение подтверждения.
Моя проблема в том, что это, кажется, только добавляет слушателя к первому элементу с классом, который он находит. Я пытался использовать querySelectorAll
но это не сработало.
var deleteLink = document.querySelector('.delete');
deleteLink.addEventListener('click', function(event) {
event.preventDefault();
var choice = confirm("sure u want to delete?");
if (choice) {
return true;
}
});
Список:
<?php
while($obj=$result->fetch_object())
{
echo '<li><a class="delete" href="removeTruck.php?tid='.$obj->id.'">'.$obj->id.'</a>'
. '<a href="#" class="delete"></a>
</li>'."\n";
}
/* free result set */
$result->close();
$mysqli->close();
?>
Ответы
Ответ 1
Вы должны использовать querySelectorAll
. Он возвращает NodeList, однако querySelector
возвращает только первый найденный элемент:
var deleteLink = document.querySelectorAll('.delete');
Затем вы должны выполнить цикл:
for (var i = 0; i < deleteLink.length; i++) {
deleteLink[i].addEventListener('click', function(event) {
if (!confirm("sure u want to delete " + this.title)) {
event.preventDefault();
}
});
}
Также вы должны запретить удаление только в том случае, если confirm === false
.
Также стоит отметить, что return false/true
полезен только для обработчиков событий, связанных с onclick = function() {...}
. Для addEventListening
вы должны использовать event.preventDefault()
.
Демо: http://jsfiddle.net/Rc7jL/3/
версия ES6
Вы можете сделать его немного более чистым (и более безопасным замыкание в петле) с помощью Array.prototype.forEach вместо for-loop:
var deleteLinks = document.querySelectorAll('.delete');
Array.from(deleteLinks).forEach(link => {
link.addEventListener('click', function(event) {
if (!confirm(`sure u want to delete ${this.title}`)) {
event.preventDefault();
}
});
});
<суб > В примере выше используется Array.from и строки шаблона из стандарта ES2015,
Суб >
Ответ 2
Проблема с использованием цикла querySelectorAll
и for
заключается в том, что он создает целый новый обработчик событий для каждого элемента массива.
Иногда это именно то, что вы хотите. Но если у вас много элементов, может быть более эффективным создание одного обработчика событий и привязка его к элементу контейнера. Затем вы можете использовать event.target
для обращения к определенному элементу, который вызвал событие:
document.body.addEventListener("click", function (event) {
if (event.target.classList.contains("delete")) {
var title = event.target.getAttribute("title");
if (!confirm("sure u want to delete " + title)) {
event.preventDefault();
}
}
});
В этом примере мы создаем только один обработчик событий, который привязан к элементу body
. Всякий раз, когда нажимается элемент внутри body
, событие click
пузырится до нашего обработчика событий.
Ответ 3
Короткое и приятное решение с использованием ES6:
document.querySelectorAll('.input')
.forEach(input => input.addEventListener('focus', this.onInputFocus));
Ответ 4
Вы должны использовать querySelectorAll
, поскольку вам нужно выбрать все элементы с указанным классом, так как querySelectorAll
- это массив, в котором необходимо выполнить повторение и добавить обработчики событий
var deleteLinks = document.querySelectorAll('.delete');
for (var i = 0; i < deleteLinks.length; i++) {
deleteLinks[i].addEventListener('click', function (event) {
event.preventDefault();
var choice = confirm("sure u want to delete?");
if (choice) {
return true;
}
});
}