2012-12-17 22 views
9

Ich habe jetzt seit ein paar Stunden damit zu kämpfen.Hinzufügen von Ereignis-Listenern zu mehreren Elementen

Ich möchte ein Ereignis-Listener für alle <select> s auf einer Seite hinzuzufügen, und ich habe dieses Stück Code wurde so weit:

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

Dies löst nur die Warnung, wenn die Seite geladen wird, und nicht, wenn Ich ändere den Wert in irgendeinem meiner <select> s.

Kann ich bitte einen Schubs in die richtige Richtung bekommen? :-)

Antwort

9

Sie müssen dafür gibt es anonyme Funktion haben, wie Sie alert() Funktion sofort in Ihrem Beispiel aufrufen:

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

Vorerst nach Ihren Code addEventListener versucht Ergebnis undefined (Rückkehr von alert() hinzufügen Funktion).

Oder Sie können einfach Funktion Handler für das passieren:

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

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

Hinweis: dass, indem sie somefunction(arg[, arg...]) rufen Sie nicht funktionieren verweisen, sondern auf welche Funktion zurückkehrt.

+1

Oh. Ich war mir sicher, dass ich das versucht habe, aber anscheinend nicht. Vielen Dank! Edit: Ich verstehe. Jetzt, wo du es erwähnst, macht es Sinn für mich. –

+0

@perplexor Sind Sie sicher? Ich sehe keinen weiteren Fehler in Ihrem Code. – antyrat

+0

Natürlich habe ich es unter anderen Umständen versucht, weshalb es damals nicht funktionierte. Aber jetzt funktioniert es mit Ihrer Lösung! –

0

Sie sind die alert() Funktion sofort ausgeführt wird, müssen Sie die addEventListener Funktion eine Funktion stattdessen passieren, 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

Abgesehen von den alert in einer Funktion Einwickeln, wie bereits erwähnt, nicht verwenden getElementsByTagName für jede Iteration der Schleife:

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

Sie haben die Liste der select Elemente einer variablen gespeichert, dann ist es nicht notwendig, nicht zu erwähnen, ineffizient get all diesen Elemente, jede Schleifeniteration.

+0

Guter Punkt! Ich habe tatsächlich nur "Versuch und Irrtum" verwendet, um das gewünschte Ergebnis zu erzielen. Deshalb hat mir das gefallen. Vielen Dank! –

+0

Kein Problem, "Trial and Error" ist meiner Meinung nach der einzige Weg, um wirklich zu programmieren, so gute Arbeit: P – Cerbrus

+0

Hilfreiche Antwort, kennen Sie einen schnelleren Weg? Ich meine getElementByTagName kann ein wenig langsam – M98

1

Ich habe die folgende einfache Funktion erstellt, die über alle Elemente iteriert, die mit selector übereinstimmen, und einen Ereignis-Listener für event mit dem übergebenen handler hinzufügen.

Dieses ähnliche Funktionalität für jQuery $(selector).on(event, handler) der

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

    useCapture = useCapture || false; 

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

Also für den OP der Weg, um diese Funktion zu nutzen, wie so wäre:

für Event listener for current and future elements meine Antwort
addEventListeners("select", "change", function(evt){ console.log(evt); }); 

Siehe auch

0

Event Bubbling ist das wichtigste Konzept in JavaScript. Wenn Sie also ein Ereignis direkt auf DOM hinzufügen können, können Sie einige Codezeilen speichern:

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