300

我目前正在尝试编写一些 JavaScript 来获取已单击的类的属性。我知道要以正确的方式做到这一点,我应该使用事件侦听器。我的代码如下:

var classname = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

classname.addEventListener('click', myFunction(), false);

每次单击其中一个类来告诉我属性时,我都希望得到一个警报框,但不幸的是,这不起作用。有人可以帮忙吗?

注意-我可以很容易地做到这一点,jQuery但我不想使用

4

6 回答 6

529

这应该有效。getElementsByClassName返回匹配条件的元素的数组类似数组的对象(请参阅编辑)。

var elements = document.getElementsByClassName("classname");

var myFunction = function() {
    var attribute = this.getAttribute("data-myattribute");
    alert(attribute);
};

for (var i = 0; i < elements.length; i++) {
    elements[i].addEventListener('click', myFunction, false);
}

jQuery 为您完成了循环部分,您需要在纯 JavaScript 中完成。

如果您有ES6 支持,您可以将最后一行替换为:

    Array.from(elements).forEach(function(element) {
      element.addEventListener('click', myFunction);
    });

注意:较旧的浏览器(如 IE6、IE7、IE8)不支持getElementsByClassName,因此它们返回undefined.


更正

getElementsByClassName不返回数组,但大多数情况下返回 HTMLCollection,或者在某些浏览器中返回 NodeList ( Mozilla ref )。这两种类型都是类数组,(意味着它们具有长度属性并且可以通过它们的索引访问对象),但不是严格意义上的数组或继承自数组(意味着可以在数组上执行的其他方法不能在这些类型上执行)。

感谢用户@Nemo指出这一点并让我深入了解。

于 2013-10-29T10:31:53.390 回答
40

使用现代 JavaScript 可以这样做:

const divs = document.querySelectorAll('.a');

divs.forEach(el => el.addEventListener('click', event => {
  console.log(event.target.getAttribute("data-el"));
}));
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>Example</title>
  <style>
    .a {
      background-color:red;
      height: 33px;
      display: flex;
      align-items: center;
      margin-bottom: 10px;
      cursor: pointer;
    }
    
    .b {
      background-color:#00AA00;
      height: 50px;
      display: flex;
      align-items: center;
      margin-bottom: 10px;
    }
  </style>
</head>
<body>
  <div class="a" data-el="1">1</div>
  <div class="b" data-el="no-click-handler">2</div>
  <div class="a" data-el="3">11</div>
</body>
</html>

  1. 按类名获取所有元素
  2. 使用 forEach 遍历所有元素
  3. 在每个元素上附加一个事件监听器
  4. 用于event.target检索特定元素的更多信息
于 2020-02-18T18:50:19.010 回答
20

* 对此进行了编辑,以允许目标类的孩子触发事件。有关详细信息,请参阅答案底部。*

将事件侦听器添加到经常添加和删除项目的类的替代答案。这受到 jQueryon函数的启发,您可以在其中为事件正在侦听的子元素传递选择器。

var base = document.querySelector('#base'); // the container for the variable content
var selector = '.card'; // any css selector for children

base.addEventListener('click', function(event) {
  // find the closest parent of the event target that
  // matches the selector
  var closest = event.target.closest(selector);
  if (closest && base.contains(closest)) {
    // handle class event
  }
});

小提琴:https ://jsfiddle.net/u6oje7af/94/

这将侦听元素的子base元素的点击,如果点击的目标有一个匹配选择器的父元素,则将处理类事件。您可以根据需要添加和删除元素,而无需向单个元素添加更多点击侦听器。即使是在添加此侦听器之后添加的元素,这也会捕获它们,就像 jQuery 功能一样(我想这在引擎盖下有点相似)。

这取决于传播的事件,因此如果您stopPropagation在其他地方进行事件,这可能不起作用。此外,该closest功能显然与 IE 存在一些兼容性问题(什么没有?)。

如果您需要重复听这种类型的动作,这可以变成一个函数,比如

function addChildEventListener(base, eventName, selector, handler) {
  base.addEventListener(eventName, function(event) {
    var closest = event.target.closest(selector);
    if (closest && base.contains(closest)) {
      // passes the event to the handler and sets `this`
      // in the handler as the closest parent matching the
      // selector from the target element of the event
      handler.call(closest, event);
    }
  });
}

===========================================
编辑:这篇文章最初使用该matches功能事件目标上的 DOM 元素,但这将事件的目标限制为仅直接类。它已更新为使用该closest函数,允许所需类的子级事件也触发事件。原始matches代码可以在原始小提琴中找到: https ://jsfiddle.net/u6oje7af/23/

于 2018-06-17T23:34:53.370 回答
12

您可以使用以下代码:

document.body.addEventListener('click', function (evt) {
    if (evt.target.className === 'databox') {
        alert(this)
    }
}, false);
于 2019-02-23T18:45:18.477 回答
4

您可以使用 querySelectorAll 来选择所有类并循环访问它们以分配 eventListener。if 条件检查它是否包含类名。

const arrClass = document.querySelectorAll(".className");
for (let i of arrClass) {
  i.addEventListener("click", (e) => {
    if (e.target.classList.contains("className")) {
        console.log("Perfrom Action")
    }
  })
}
于 2020-10-01T08:31:02.640 回答
0

还要考虑如果您单击一个按钮,事件侦听器的目标不一定是按钮本身,而是您单击的按钮内的任何内容。您可以使用currentTarget属性引用分配了侦听器的元素。这是现代 ES 中使用单个语句的一个很好的解决方案:

    document.querySelectorAll(".myClassName").forEach(i => i.addEventListener(
        "click",
        e => {
            alert(e.currentTarget.dataset.myDataContent);
        }));
于 2020-12-13T18:38:25.213 回答