JavaScript click event listener on class

后端 未结 5 983
悲&欢浪女
悲&欢浪女 2020-11-22 10:19

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 listene

相关标签:
5条回答
  • 2020-11-22 10:46

    This should work. getElementsByClassName returns an array Array-like object(see edit) of the elements matching the criteria.

    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.

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

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

    Note: Older browsers (like IE6, IE7, IE8) don´t support getElementsByClassName and so they return undefined.


    EDIT : Correction

    getElementsByClassName doesnt 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)

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

    0 讨论(0)
  • 2020-11-22 10:55

    * 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 on function where you can pass in a selector for a child element that the event is listening on.

    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/

    This will listen for clicks on children of the base element 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).

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

    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 matches function 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 closest function instead, allowing for events on children of the desired class to trigger the events as well. The original matches code can be found at the original fiddle: https://jsfiddle.net/u6oje7af/23/

    0 讨论(0)
  • 2020-11-22 11:01

    With modern JavaScript it can be done like this:

    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.target to retrieve more information for specific element
    0 讨论(0)
  • 2020-11-22 11:01

    You can use the code below:

    document.body.addEventListener('click', function (evt) {
        if (evt.target.className === 'databox') {
            alert(this)
        }
    }, false);
    
    0 讨论(0)
  • 2020-11-22 11:13

    Yow can use querySelectorAll to select all the classes and loop through them to assign the eventListener. The if condition checks if it contains the class name.

    const arrClass = document.querySelectorAll(".className");
    for (let i of arrClass) {
      i.addEventListener("click", (e) => {
        if (e.target.classList.contains("className")) {
            console.log("Perfrom Action")
        }
      })
    }
    
    0 讨论(0)
提交回复
热议问题