Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding event listeners to multiple elements

I've been struggling with this for a good couple of hours now.

I want to add an event listener to all <select>s on a page and I've got this piece of code so far:

onload = function(e) {
    sels = document.getElementsByTagName('select');
    for(i=0; i<sels.length; i++) {
        sels[i].addEventListener('change', alert('test!'), false);
    }
}

This only triggers the alert when the page is loaded and not when I change the value in any of my <select>s.

Can I get a nudge in the right direction, please? :-)

like image 877
Christian Lundahl Avatar asked Dec 17 '12 14:12

Christian Lundahl


People also ask

Can I add event listener to multiple elements?

In other words, how to call addEventListener() on multiple elements at the same time? You can do this in 2 ways. One is using a loop, the other is using event bubbling.

Can I add event listener to all elements of class?

To add an event listener to all elements with class: Use the document. querySelectorAll() method to select the elements by class. Use the forEach() method to iterate over the collection of elements.


3 Answers

Aside from wrapping the alert in a function, like mentioned before, don't use getElementsByTagName for every iteration of the loop:

onload = function(e) {
    sels = document.getElementsByTagName('select');
    for(i=0; i<sels.length; i++) {
        sels[i].addEventListener('change', function(){alert('test!')}, false);
    }
}

You have the list of select elements saved to a variable, it's not necessary, not to mention inefficient to get all these elements, each loop iteration.

like image 55
Cerbrus Avatar answered Oct 24 '22 04:10

Cerbrus


I created the following simple function, which iterates over all of the elements that match the selector, and add an event listener for the event with the passed handler.

This is similar functionality for jQuery's $(selector).on(event, handler)

function addEventListeners(selector, event, handler, useCapture){

    useCapture = useCapture || false;

    Array.prototype.forEach.call(
        document.querySelectorAll(selector)
       ,function(el, ix) { 
          el.addEventListener(event, handler, useCapture);
        }
    );
}

So for the OP the way to use this function would be like so:

addEventListeners("select", "change", function(evt){ console.log(evt); });

See also my answer for Event listener for current and future elements

like image 44
isapir Avatar answered Oct 24 '22 04:10

isapir


You need to have there anonymous function for that as you invoke alert() function immediately in your example:

 ... .addEventListener('change', function() { alert('test!')}, false ...

For now according to your code addEventListener tries to add result of undefined (return of alert() function).

Or you can just pass function handler for that:

function alertMe() {
    alert( 'test!' );
}
...

... .addEventListener('change', alertMe, false ...

Note: that by making somefunction(arg[, arg...]) call you reference not to function, but to what function returns.

like image 33
antyrat Avatar answered Oct 24 '22 04:10

antyrat