为同一个类的元素添加点击事件监听器

IT技术 javascript
2021-01-23 18:54:40

我有一个删除 id 的列表视图。我想为具有特定类的所有元素添加一个侦听器并发出确认警报。

我的问题是,这似乎只将侦听器添加到它找到的类的第一个元素。我尝试使用,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();
?>
5个回答

你应该使用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 循环,您可以使它更简洁(和更安全的闭环循环

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.fromES2015 标准中的模板字符串

我试过了,但它没有工作我为(int i=0...)deletelink[i].addEventListener('click', function(event) { event.preventDefault(); var choice = confirm("确定你想要删除?"); if (choice) { return true; } });
2021-03-16 18:54:40
另一个巧妙的技巧是使用扩展运算符,它适用于类似数组的对象。因此Array.from(deleteLinks),您可以这样做[...deleteLinks]我认为Array.from更清楚,但只是一个值得指出的整洁的事情。
2021-03-18 18:54:40
我想我第一次做的时候也做了同样的事情谢谢你:))
2021-03-28 18:54:40
看看我设置的演示。
2021-04-03 18:54:40
@OlivierBoissé 因为forEach是 Array 的一种方法。写这个答案时,NodeList 没有实现它。即使现在它也不能在像 IE 这样的旧浏览器中工作(11?)。
2021-04-10 18:54:40

使用querySelectorAllfor循环的问题在于它为数组中的每个元素创建了一个全新的事件处理程序

有时这正是你想要的。但是,如果您有许多元素,创建单个事件处理程序并将其附加到容器元素可能会更有效。然后,您可以使用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事件就会冒泡到我们的事件处理程序。

将 click 事件附加到实际的父容器元素而不是主体可能会更好。
2021-03-20 18:54:40

一个简短而甜蜜的解决方案,使用 ES6:

document.querySelectorAll('.input')
      .forEach(input => input.addEventListener('focus', this.onInputFocus));

您必须使用,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;
        }
    });
}
这个答案有点旧(3.5 岁),但我必须纠正它querySelectorAll不返回 a Array,而是 a NodeList,它看起来像 aArray但没有相同的方法。
2021-03-12 18:54:40

(ES5) 我使用 forEach 迭代 querySelectorAll 返回的集合,它运行良好:

document.querySelectorAll('your_selector').forEach(item => { /* do the job with item element */ });