Javascript Event Bubbling
Event-Bubbling ist ein grundlegendes Konzept in Javascript. Was ist aber Event-Bubbling und wie kann man es unterbinden? Diese Fragen werden in dem folgenden Beitrag anhand von einfachen Beispielen Beitrag geklärt.
Javascript ist stark, weil es dem Entwickler ermöglicht Webseiten mit Interaktivität auszustatten. Und zwar mit solcher Interaktivität, die HTML, CSS oder PHP alleine nicht leisten können. Ein entscheidendes Feature, warum Javascript interaktiv ist, sind Events mit denen man Aktionen des Users behandeln kann. Event Bubbling ist dabei ein grundlegendes Konzept in Javascript. Das Event-PrinzipWenn ein DOM-Element, z. B. ein div oder ein Link angeklickt wird, löst der Browser das Klick-Event für dieses Element aus. Für andere Aktionen, z. B. das streifen eines Elements mit der Maus löst der Browser entsprechend andere Events aus z. B. das Mouseover-Event. Es gibt also im DOM für jede Useraktion das passende Element. Verschachtelte Elemente - welches Event wird ausgelöst?Interessant wird das Ganze, wenn im DOM mehrere Elemente ineinander verschachtelt sind. Z. B. so wie hier:
<div id="mein_div">mein div<span id="mein_span"> mein_span</span></div>
Wenn hier beispielsweise ein Klick auf das span-Element erfolgt, so wird ein Klick-Event für das span-Element ausgelöst aber auch eines für das div-Element. denn dieses wird ja auch angeklickt, weil sich das span-Element im div-Element befindet. Und es geht noch weiter. Auch für alle anderen umschließenden Elemente wird ein Klick-Event ausgelöst also auch für das html- und das body-Element. Deshalb nennt sich dieses Prinzip auch Event-Bubbling, weil das Event wie eine Luftblase im DOM nach oben steigt und erst am Wurzelelement des DOM, dem window-Element endet - quasi platzt. D. h. auch für das window-Element wird ein Event geworfen. Folgendes Beispiel verdeutlicht dies:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=windows-1250">
<meta name="generator" content="PSPad editor, www.pspad.com">
<title></title>
</head>
<body id="body_element">
<div id="mein_div">mein div<span id="mein_span"> mein_span</span></div>
<script type="text/javascript">
var mein_span = document.getElementById('mein_span');
// Event Handler mein_span
if (mein_span.addEventListener)
{
// W3C konforme Browser
mein_span.addEventListener("click", function(event) {
alert('mein_span');
}, false);
}
else if(mein_span.attachEvent)
{
// IE
mein_span.attachEvent("onclick", function(event) {
alert('mein_span');
}, false);
}
var mein_div = document.getElementById('mein_div');
// Event Handler mein_div
if (mein_div.addEventListener)
{
// W3C konforme Browser
mein_div.addEventListener("click", function(event) {
alert('mein_div');
}, false);
}
else if(mein_div.attachEvent)
{
// IE
mein_div.attachEvent("onclick", function(event) {
alert('mein_div');
}, false);
}
// Event Handler body_element
if (body_element.addEventListener)
{
// W3C konforme Browser
body_element.addEventListener("click", function(event) {
alert('body_element');
}, false);
}
else if(mein_div.attachEvent)
{
// IE
body_element.attachEvent("onclick", function(event) {
alert('body_element');
}, false);
}
// Event Handler window
if (window.addEventListener)
{
// W3C konforme Browser
window.addEventListener("click", function(event) {
alert('window');
}, false);
}
else if(window.document.attachEvent)
{
// IE
window.document.attachEvent("onclick", function(event) {
alert('window');
}, false);
}
</script>
</body>
</html>
Hier haben wir die gleichen verschachtelten Elemente, wie wir sie bereits im ersen Beispiel hatten. Per Javascript sind nun Event-Handler hinzugefügt worden. Wir beobachten damit die Klick-Events für die Elemente mein_span, mein_div, body und window. Für jedes Klick-Event wird per alert() ein Hinweis zum Element ausgegeben. Z. B. in Zeile 17 alert('mein_span'); Hinweis an alle Prototype-, Mootools- und JQuery-Fans (zu denen ich auch gehöre): Ich habe hier absichtlich die fundamentalen Javascript Event-Handler genutzt und nicht die schon-Cross-Browser-kompatiblen-und-super-leicht-zu-benutzenden Event-Handler dieser Bibliotheken, um hier einen grundlegenden Standard mit grundlegender Technik zu beschreiben, die für alle gleich ist. Klickt der User nun auf das span-Element, so wird zuerst das Klick-Event für dieses Element ausgelöst und per alert() 'mein_span' ausgegeben. Anschließend folgt das Klick-Event für das umschließende div, welches wir ebenfalls per alert() ausgeben. Das div befindet sich wiederum im body-Element der Seite und somit wird mit unserem Event-Handler für das body Element 'body_element' ausgegeben (Zeile 51). Nachdem wir ja für das window-Element ebenfalls einen Klick-Event-Hander definiert haben folgt zuletzt noch die Ausgabe 'window'. Jetzt reicht's ich hab' keinen Bock mehr auf bubblen Ok das klingt jetzt vielleicht ein bisschen drastisch, aber prinzipiell kann der Fall schon eintreten, dass man das Event Bubbling verhindern muss. Dazu gibt es eine Event-Eigenschaft, welche diesen Job übernimmt: cancelBubble. Folgendes Beispiel zeigt, wie es geht:
// Event Handler body_element
if (body_element.addEventListener)
{
// W3C konforme Browser
body_element.addEventListener("click", function(event) {
alert('body_element');
event.cancelBubble = true;
}, false);
}
else if(mein_div.attachEvent)
{
// IE
body_element.attachEvent("onclick", function(event) {
alert('body_element');
event.cancelBubble = true;
}, false);
}
In diesem Fall haben wir uns den Event-Handler des body-Elements von oben genommen und in den Zeilen 7 und 15 jeweils die cancleBubble-Eigenschaft des Events verändert. Demzufolge werden per alert nur noch die Meldungen für das span-, div- und body-Element ausgegeben und nicht mehr für das window-Element.
|
Kommentare
danke für die Frage!
Die Klick-Events von body und window würden dann nicht mehr kommen.