Adding event listeners to multiple elements

自古美人都是妖i 提交于 2019-11-27 03:20:37

问题


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? :-)


回答1:


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.




回答2:


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.




回答3:


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




回答4:


You are executing the alert() function immediately, you need to pass the addEventListener function a function instead, so:

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



回答5:


Event Bubbling is the important concept in javascript, so if you can add event on DOM directly, you can save some lines of code :

document.addEventListener('change', function(e){
  if(e.target.tagName=="SELECT"){
   alert('SELECT CHANGED');
  }
})


来源:https://stackoverflow.com/questions/13915702/adding-event-listeners-to-multiple-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!