Ik heb hier eerder iets geroepen over dat het IE5+ event model zuigt, laat ik dat eens onderbouwen aan de hand van een voorbeeld
In feite zijn er 2 problemen met het IE5 event model
1) IE ondersteund alleen event-bubbling, geen capturing
2) Het is onmogelijk om tijdens de bubbling-fase het element te achterhalen wat het event op dat moment verwerkt
Een voorbeeld (te testen in IE en in bijvoorbeeld Mozilla/Firebird):
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
| <html>
<head>
<title>bla2</title>
<script type="text/javascript">
function init() {
if (typeof document.attachEvent != 'undefined') {
document.getElementById('box1').attachEvent('onclick', bla_ie);
document.getElementById('box2').attachEvent('onclick', bla_ie);
} else {
// note: changing false to true will use event capturing iso bubbling
document.getElementById('box1').addEventListener('click', bla_dom, false);
document.getElementById('box2').addEventListener('click', bla_dom, false);
}
}
function bla_ie() {
// always undefined because the function is referenced instead of copied
alert(this.id);
// will always reference the element which caused the event to trigger
alert(event.srcElement.id);
}
function bla_dom(e) {
// both give the current element that is handling the event
// either in capturing of bubbling fase
alert(this.id);
alert(e.currentTarget.id);
// simular to srcElement gives the element that originally
// triggered the event
alert(e.target.id);
}
</script>
<style type="text/css">
body {
min-height: 100%;
}
#box1 {
position: absolute;
top: 10px;
left: 10px;
width: 300px;
height: 300px;
background-color: red;
}
#box2 {
position: absolute;
top: 100px;
left: 100px;
width: 100px;
height: 100px;
background-color: blue;
}
</style>
</head>
<body onload="init()">
<div id="box1">
<div id="box2"> </div>
</div>
</body>
</html> |
Je ziet hier een box in een box, beiden krijgen een onclick event toegewezen. Kijk wat er gebeurd als je op het blauwe vierkant klikt:
IE: geeft voor de eerste alert 'undefined' omdat IE enkel een referentie naar de toegewezen functie maakt in plaats van een kopie. Het this keyword verwijst dus naar het window object in plaats van het element dat op dat moment het event afhandeld (omdat IE event-bubbling gebruikt is dat op dit moment box2).
De 2e alert geeft netjes box2 als srcElement.
Vervolgens bubbled het event dus door naar onderen en triggered de onclick op box1. Hier komt het grote manko van IE dus aan het licht:
er is geen enkele manier om te achterhalen dat box1 op dit moment het event afhandelt; de 1e alert geeft nog steeds undefined, en de 2e alert nog steeds box2 omdat dat het element was wat als eerste de reeks events triggerde.
Mozilla: maakt itt IE wel een kopie van de toegewezen functie waardoor het this keyword verwijst naar het element wat op dat moment het event afhandeld. Als alternatief kan ook verwezen worden naar de currentTarget property van het event-object (wat dus als een parameter wordt doorgegeven in plaats van dat het een global property van het window object is).
Het 3e argument in addEventListener geeft aan of eventbubbling of eventcapturing gebruikt moet worden; false = bubbling, true = capturing.
We gebruiken eventbubbling in dit voorbeeld, dus het eerste element waarvan het event getriggered wordt is box2; de 1e keer dat functie bla_dom wordt uitgevoerd krijgen we dus 3x 'box2' als alert. Vervolgens bubbled het event naar box1 en verwijzen zowel this als currentTarget naar box1, en blijft target naar box2 verwijzen gelijk srcElement in het IE model.
Als je nu het 3e argument voor addEventListener wijzigt naar true zal je zien dat de event-volgorde omdraait (van onder naar boven)
Hoe krijg je het in IE dan toch voor elkaar om te achterhalen welk element het event afhandelt op een bepaald moment in de bubbling fase? Simpel, het DOM level 1 event model gebruiken:
element.onclick = handler;
binnen de handler kan je dan toch gebruik maken van het this keyword. Het grootste nadeel van dit model is dat je niet meerdere handlers aan 1 event kan toekennen (en dus ook niet eenvoudig weer kan verwijderen), en dat je alleen gebruik kan maken van event-bubbling.