onChange Event "global" abfragen?

DataFox

Erfahrenes Mitglied
Guten Abend liebe Experten,

ich habe auf einer Seite mehrere Formulare wo SELECT-Tags vorkommen. Sobald sich irgend etwas in dem Formular tut, soll eine Funktion aufgerufen werden.

Momentan kriege ich es nicht hin, das mir der Browser (MSIE 6.0 / Firefox) bei einem onchange-Event einen Alert ausspuckt:

window.document.onchange = function() {
alert('etwas wurde geändert!');
}

eigentlich müsste das doch so laufen. Denn das hier funktioniert auch:

window.document.onmouseover = function() {
alert('die maus ist drauf!');
}

welche anderen "schlauen Wege" gibt es, um global auf einen Event zu lauschen? Ich möchte nicht jedem Element im HTML-Code einen riesigen Rattenschwanz aus "onChange=..." mitgeben.

Danke
Laura
 
Hi,

den onchange-Event gibt es für das document-Objekt nicht (siehe Mozilla, MSDN).

Eine andere Möglichkeit ist, im onload-Event alle Selectelemente zu durchlaufen und einen onchange-Handler zu registrieren.
Code:
<html>
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">

<script type="text/javascript">
<!--
function derAlert(strMsg){
  alert(strMsg);
}

window.onload = function(){
  // Select-Array mit allen Selectelementen erstellen
  var arrSel = document.getElementsByTagName("select");

  // Select-Array durchlaufen
  for(var i=0; i<arrSel.length; i++){
    // onchange-Event eine Funktion zuweisen
    arrSel[i].onchange = function(){ derAlert(this.id);}
  }
}
//-->
</script>
</head>
<body>
<select id="selID1">
  <option>fünf</option>
  <option>sechs</option>
</select>
<select id="selID2">
  <option>eins</option>
  <option>zwei</option>
</select>
<select id="selID3">
  <option>drei</option>
  <option>vier</option>
</select>
</body>
</html>
Ciao
Quaese
 
Danke Dir für die Hilfe! Was mache ich, wenn per Ajax nachträglich ein Select in den Content geladen wird?

Wenn ich den Code richtig verstehe, würde dieses neu hinzugeladene Element dann nicht erkannt bzw. es hätte den Eventhandler nicht. Oder?

Kannste mir nen Tipp geben was man in so einem Fall tun müsste? Stehe gerade auf dem Schlauch. Glaube, eine Funktion welche alle 2 Sekunden aufgerufen wird und allen SELECT's den Eventhandler verpasst wäre unschlau, weil die anderen den Handler immer öfter bekommen. Oder?

Danke
Laura
 
Hi,

du kannst ja beim Durchlaufen der Selectfelder prüfen, ob sich im onchange-Handler bereits eine Funktion befindet. Nur wenn der Event noch nicht behandelt wird, weist du eine Routine zu.

Hier der angepasste JS-Teil:
Code:
function derAlert(objSel){
  alert(typeof objSel.onchange);
}

function setHandler(){
  // Select-Array mit allen Selectelementen erstellen
  var arrSel = document.getElementsByTagName("select");

  // Select-Array durchlaufen
  for(var i=0; i<arrSel.length; i++){
    if(typeof arrSel[i].onchange != "function"){
      // onchange-Event eine Funktion zuweisen
      arrSel[i].onchange = function(){ derAlert(this);}
    }
  }
}

window.onload = function(){
  setHandler();
}
Die Funktion setHandler kann jetzt auch aus der Ajax-Routine heraus aufgerufen werden, nachdem die neue Selectgruppe ins Dokument eingefügt wurde.
Code:
// ... 
xmlHttp.onreadystatechange = function () {
  if(xmlHttp.readyState == 4){
    if(xmlHttp.status == 200){
      // Neue Selectbox in ein Element mit der ID "newSel_01" einfügen
      document.getElementById("newSel_01").innerHTML = unescape(xmlHttp.responseText);
      setHandler();
    }
  }
};
// ...
Vielleicht hilft dir das weiter.

Ciao
Quaese
 
Wow, danke!

Wie ist das denn, wenn vorher schon eine onchange-Funktion durch ein andere Script oder inline notiert wurde?

Kann man irgendwie abfragen welche Funktionen an einem Event hängen oder ausgelöst werden würden? Klingt etwas konfus...

Danke
Laura
 
Hi,

ist schon ein onchange-Handler notiert, würde das Selectelement nicht bearbeitet werden. Willst du eine schon vorhandene Funktion beibehalten, musst du sie "zwischenspeichern" und bei Bedarf zusätzlich aufrufen.

Das könnte in Anlehnung an obiges Beispiel folgendermassen aussehen:
Code:
arrSel[i].onchange_old = arrSel[i].onchange;
arrSel[i].onchange = function(){
  this.onchange_old();
  derAlert(this);
}
Allerdings wird es zu Problemen kommen, wenn du diese Vorgehensweise häufiger in einem Element benutzt, da onchange_old später wieder auf onchange_old zugreifen will - das ist jedoch bereits überschrieben worden.

Auf den Inhalt von Eventhandlern kannst du über ihren Namen und auf den enthaltenen String mit Hilfe der Methode toString zugreifen.
Code:
alert(objSel.onchange.toString());
Den String könntest du mit regulären Ausdrücken überprüfen, ob bekannte Funktionsaufrufe enthalten sind. Ich bin aber skeptisch, ob das jedoch zuverlässig arbeitet, da Funktiosaufrufe auch implizit ausgeführt werden können.

Ciao
Quaese
 

Neue Beiträge

Zurück