Felix Riesterer: Blubbern unterdrücken... wie funktioniert's genau?

Beitrag lesen

Lieber Gernot,

auch ich habe wild herumprobiert. Als ich den onclick="aufzu(this)" mal mit alert(this.onclick) "ansehen" wollte, da kam im Dialogfenster etwas sehr interessantes:

  
function onclick(event) {  
aufzu(this);  
}

Das bedeutet, dass der Mozilla intern eine Variable "event" in der onclick-Funktion führt, innerhalb derer dann der Code aus dem onclick-Attribut ausgeführt wird. Damit hat man im Eventhandler-Attribut des Mozilla (wahrscheinlich in allen Eventhandlern wie z.B. auch in "mouseover" oder "onchange") immer die Variable "event" zur Verfügung, die eine Referenz des Events enthält.

<html>
<head>
<title>Bubbling verhindern</title>
<meta name="author" content="Gernot Back">
<meta name="generator" content="Ulli Meybohms HTML EDITOR">
<script language="JavaScript">
[code lang=javascript]
function stoppen (e) {
  if(window.event)
    window.event.cancelBubble=true;
  else
    e.stopPropagation();
}


> </script>  
> </head>  
> <body >  
> <p onclick="`alert('das kitzelt!')`{:.language-javascript}"><a href="#" onclick="`stoppen(event)`{:.language-javascript}">Event melden</a></p>  
> </body>  
> </html>[/code]  
  
In Deinem Beispiel übergibst Du im onclick-Eventhandler einen Funktionsaufruf mit eben obiger Variable "event". In Deiner Funktion taufst Du sie bei Übergabe in "e" um, hast damit die Referenz des Events nun in "e" verfügbar. Damit stimmen unsere Beobachtungen überein und wir haben eine Erklärung gefunden!  
  
Im IE sieht das ja etwas anders aus... Der kennt die windows-Eigenschaft "event", die wiederum eine Bool'sche Eigenschaft "cancelBubble" hat. In windows.event ist wohl gerade das aktuelle Event gespeichert. Auch im IE kann man das onclick-Attribut mit "alert(this);" prüfen. Heraus kommt dann eine Funktion (wie beim Mozilla), die jedoch eine anonyme Funktion ohne übergebenen Parameter ist, und die (auch wie beim Mozilla) den im onclick-Attribut gespeicherten Code ausführt. Damit steht im Eventhandler-Attribut des IE die Variable "event" \_nicht\_ zur Verfügung.  
  
Also wie mache ich das Browser-übergreifend? Wenn ich im onclick-Attribut zum Beispiel notiere "aufzu([wert1, wert2], event);", dann kann ich in der Funktion aufzu() nicht prüfen (andere sind vielleicht schlauer als ich), ob in "event" nun tatsächlich eine Referenz des Events gespeichert ist, da mir auch der IE bei alert(event) ein "object" liefert. Ich habe das ausprobiert. Eine Browserweiche à la `if(event) { mozilla } else { IE }`{:.language-javascript} klappt nicht, da event im IE nicht undefined und nicht false ist. Ein Workaround für den IE wäre sehr umständlich, da ich in \_jedes\_ onclick-Attribut eine Prüfung auf das Vorhandensein von "event" einbauen müsste, um bei Nichtvorhandensein eine Variable "event" mit dem Wert false zu definieren, was den Inhalt des onclick-Attributes im HTML-Code extrem aufbläht (bei etwa 1500 Zeilen Dateibaum!).  
  
=> Ich bleibe bei meiner Lösung mit zwei globalen Variablen, bei der das Event Bubbling zwar nicht ausgeschaltet, aber doch effektiv ausgehebelt wird, da ich ansonsten meinen HTML-Quelltext sowas von aufblähen müsste (lange onclick-Attribute), dass die unelegantere Lösung tatsächlich die einfachere ist.  
  
Vielen Dank für Deine Forschungen! Wir haben beide dazugelernt! ;-)  
  
Liebe Grüße aus Ellwangen,  
  
Felix Riesterer.