类上的 JavaScript 单击事件侦听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19655189/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 16:21:34  来源:igfitidea点击:

JavaScript click event listener on class

javascriptdom-events

提问by 30secondstosam

I'm currently trying to write some JavaScript to get the attribute of the class that has been clicked. I know that to do this the correct way, I should use an event listener. My code is as follows:

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

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

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

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

I was expecting to get an alert box every time I clicked on one of the classes to tell me the attribute but unfortunately this does not work. Can anyone help please?

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

(Note- I can quite easily do this in jQuerybut I would NOTlike to use it)

-我可以很容易地做到这一点jQuery,但我喜欢使用它

回答by Anudeep Bulla

This should work. getElementsByClassNamereturns an arrayArray-like object(see edit) of the elements matching the criteria.

这应该有效。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 does the looping part for you, which you need to do in plain JavaScript.

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

If you have ES6 supportyou can replace your last line with:

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

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

Note: Older browsers (like IE6, IE7, IE8) don′t support getElementsByClassNameand so they return undefined.

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



EDIT : Correction

编辑:更正

getElementsByClassNamedoesnt return an array, but a HTMLCollection in most, or a NodeList in some browsers (Mozilla ref). Both of these types are Array-Like, (meaning that they have a length property and the objects can be accessed via their index), but are not strictly an Array or inherited from an Array. (meaning other methods that can be performed on an Array cannot be performed on these types)

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

Thanks to user @Nemofor pointing this out and having me dig in to fully understand.

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

回答by obermillerk

* This was edited to allow for children of the target class to trigger the events. See bottom of the answer for details. *

* 这被编辑以允许目标班级的孩子触发事件。有关详细信息,请参阅答案底部。*

An alternative answer to add an event listener to a class where items are frequently being added and removed. This is inspired by jQuery's onfunction where you can pass in a selector for a child element that the event is listening on.

将事件侦听器添加到经常添加和删除项目的类的替代答案。这是受 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
  }
});

Fiddle: https://jsfiddle.net/u6oje7af/94/

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

This will listen for clicks on children of the baseelement and if the target of a click has a parent matching the selector, the class event will be handled. You can add and remove elements as you like without having to add more click listeners to the individual elements. This will catch them all even for elements added after this listener was added, just like the jQuery functionality (which I imagine is somewhat similar under the hood).

这将侦听对base元素子元素的点击,如果点击的目标具有与选择器匹配的父元素,则将处理类事件。您可以随意添加和删除元素,而无需为单个元素添加更多点击侦听器。即使对于在添加此侦听器之后添加的元素,这也会捕获它们,就像 jQuery 功能一样(我认为这在幕后有些相似)。

This depends on the events propagating, so if you stopPropagationon the event somewhere else, this may not work. Also, the closestfunction has some compatibility issues with IE apparently (what doesn't?).

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

This could be made into a function if you need to do this type of action listening repeatedly, like

如果您需要重复执行此类操作,则可以将其制成一个函数,例如

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);
    }
  });
}

=========================================
EDIT: This post originally used the matchesfunction for DOM elements on the event target, but this restricted the targets of events to the direct class only. It has been updated to use the closestfunction instead, allowing for events on children of the desired class to trigger the events as well. The original matchescode can be found at the original fiddle: https://jsfiddle.net/u6oje7af/23/

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

回答by Rajat kumar

You can use the code below:

您可以使用以下代码:

document.body.addEventListener('click', function (evt) {
    if (evt.target.className === 'databox') {
        alert(this)
    }
}, false);

回答by V. Sambor

With modern JavaScript it can be done like this:

使用现代 JavaScript 可以这样完成:

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

divs.forEach(el => el.addEventListener('click', event => {
  console.log(event.target.classList[1]);
}));
<!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 a-1">1</div>
  <div class="b">2</div>
  <div class="a a-2">11</div>
</body>
</html>

  1. Gets all elements by class name
  2. Loops over all elements with using forEach
  3. Attach an event listener on each element
  4. Uses event.targetto retrieve more information for specific element
  1. 按类名获取所有元素
  2. 使用 forEach 遍历所有元素
  3. 在每个元素上附加一个事件侦听器
  4. 用于event.target检索特定元素的更多信息