FireFox event model failure

V

VK

My original idea of two trains, however pictural it was, appeared to be
wrong. The truth seems to be even more chaotic.

IE implements its standard down-up model: any mouse event goes from the
deepest visible element to the top. By carefully studying fromElement
and toElement properties, one can handle events on any point of their
way up.

NN/FF implements a "Russian hills" style: mouse events go first
up->down (window->deepest element), and right away after that it goes
down->up (deepest element->window). On theory you can handle events
during any phase on any level. On practice this implementation has some
major flaws. I don't have NN handy right now, but in FF we have:

SomeElement.addEventListener('mouseout', test, true)

This statement supposedly forces test() to capture events on the
up->down phase. A simple test show that it fails to work. Both
addEventListener('mouseout', test, true) and
addEventListener('mouseout', test, false) capture only down->up phase
(bubbling).
Eine Frage fuer Million Dollar: what the first phase for anyway?


The real killer is here: event object in FF is not exposed to inline
event capturers!
<ul onMouseOver="f1()" onMouseOut="f2()"> as well as
<ul onMouseOver="f1(e)" onMouseOut="f2(e)">
gives you undefined for e.
Thus inline capturers are really good for nothing in FF, except maybe
for alert("Hello world!") stuff. I don't know where did they get
such idea, certainly not from my books and not from W3 papers.
I also guess that the event object in this case is not exposed neither
to the user nor to the program core itself. This explains why inline
capturers randomly fail to work depending on the mouse movement
direction and even movement speed.

This actually answers my question: is there a simple universal way to
handle events from inline capturers? The answer is: NO, because of FF
global failure.

For a situation like
<ul id="UL1">
<li><a href="javascript:void(0)">Item 1</a></li>
<li><a href="javascript:void(0)">Item 2</a></li>
<li><a href="javascript:void(0)">Item 3</a></li>
</ul>
the only way to properly handle mouse events from <ul> is to attach
event handlers on onload, and later study target properties to see if
this event really from <ul> or from some underlaying element.
 
V

VK

Test case for phase capture failure below.
Move mouse over the list 1 and 2. Expected:
list 1 eventPhase = 1 (Charly down)
list 2 eventPhase = 2 (Charly up)
(actually should be 2 and 3 by W3, but it's ok, they decided to keep
first element on 0)

Results: eventPhase = 2 in both case (Charly up)


<html>
<head>
<title>FireFox test</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<script>
var out = null;
function init() {
out = document.forms[0].elements[0];
document.getElementById('UL1').addEventListener('mouseout',test,true);

document.getElementById('UL2').addEventListener('mouseout',test,false);
}

function test(e) {
out.value+= e.eventPhase + ' ';
}
</script>
<style type="text/css">
<!--
/* this to prevent ul's to take
the whole page width
so you could slip your mouse from the right */
ul { width: 20%}
-->
</style>
</head>
<body bgcolor="#FFFFFF" onload="init()">
<h4>Test Case</h4>
<ul id="UL1">
<li><a href="javascript:void(0)">Item 1</a></li>
<li><a href="javascript:void(0)">Item 2</a></li>
<li><a href="javascript:void(0)">Item 3</a></li>
</ul>
<ul id="UL2">
<li><a href="javascript:void(0)">Item 1</a></li>
<li><a href="javascript:void(0)">Item 2</a></li>
<li><a href="javascript:void(0)">Item 3</a></li>
</ul>
<form>
<textarea cols="50" rows="4"></textarea>
</form>
<p>&nbsp;</p>
</body>
</html>
 
M

Martin Honnen

VK said:
Test case for phase capture failure below.
Move mouse over the list 1 and 2. Expected:
list 1 eventPhase = 1 (Charly down)
list 2 eventPhase = 2 (Charly up)
(actually should be 2 and 3 by W3, but it's ok, they decided to keep
first element on 0)

Results: eventPhase = 2 in both case (Charly up)

2 is at target.
There is indeed a bug in some Mozilla releases where eventPhase always
gives 2
<https://bugzilla.mozilla.org/show_bug.cgi?id=245569>
but this bug has been fixed in Mozilla trunk builds.
 
L

Lasse Reichstein Nielsen

VK said:
NN/FF implements a "Russian hills" style: mouse events go first
up->down (window->deepest element), and right away after that it goes
down->up (deepest element->window).

Correct. That is how the event handling model is defined in the W3C
DOM 2 Events specification, and Gecko implements it correctly.
In particular, it's specified here:
On theory you can handle events during any phase on any level.

Correct, as long as event propagation isn't stopped before the event
hits that level.
On practice this implementation has some major flaws. I don't have
NN handy right now, but in FF we have:

SomeElement.addEventListener('mouseout', test, true)

This statement supposedly forces test() to capture events on the
up->down phase.

Correct. The third argument is also called "capture", and the up->down
phase is called the capture phase.
A simple test show that it fails to work. Both
addEventListener('mouseout', test, true) and
addEventListener('mouseout', test, false) capture only down->up phase
(bubbling).

No. It works fine. Try this:
---
<div id="bar"><div id="baz">XXXX</div></div>
<script type="text/javascript">
var bar = document.getElementById("bar");
bar.addEventListener("click", function(event) {
alert(["up", event.currentTarget.id, event.target.id]); }, false);
bar.addEventListener("click", function(event) {
alert(["down", event.currentTarget.id, event.target.id]); }, true);
var baz = document.getElementById("baz");
baz.addEventListener("click", function(event) {
alert(["hit", event.currentTarget.id, event.target.id]); }, false);
</script>
---
Then click on the "XXXX" :)
Eine Frage fuer Million Dollar: what the first phase for anyway?

The capture phase, not the bubbleing phase.
The real killer is here: event object in FF is not exposed to inline
event capturers!
<ul onMouseOver="f1()" onMouseOut="f2()"> as well as
<ul onMouseOver="f1(e)" onMouseOut="f2(e)">

That didn't work in IE either. In intrinsic event handlers, the event
is available as the variable "event". IE makes it a global variable,
other browsers make it local.
gives you undefined for e.

As it should. Nobody have declared any variable called "e".
Thus inline capturers are really good for nothing in FF, except maybe
for alert("Hello world!") stuff. I don't know where did they get
such idea, certainly not from my books and not from W3 papers.

There is no standard for how events are propagated to intrinsic event
handlers, but the "event" variable has been defacto standard since ...
Netscape 2, I think.
I also guess that the event object in this case is not exposed neither
to the user nor to the program core itself. This explains why inline
capturers randomly fail to work depending on the mouse movement
direction and even movement speed.

I have no idea what these failures are, but this is not the reason for
them.
This actually answers my question: is there a simple universal way to
handle events from inline capturers? The answer is: NO, because of FF
global failure.

Big words. Now eat them :)
For a situation like
<ul id="UL1">
<li><a href="javascript:void(0)">Item 1</a></li>
<li><a href="javascript:void(0)">Item 2</a></li>
<li><a href="javascript:void(0)">Item 3</a></li>
</ul>
the only way to properly handle mouse events from <ul> is to attach
event handlers on onload, and later study target properties to see if
this event really from <ul> or from some underlaying element.

<ul id="UL1" onclick="var tgt = event.target||event.srcElement;//IE sucks
if (tgt == this) { alert('event on UL!'); }">
....


Good luck
/L
 
V

VK

event.target||event.srcElement­

Oh! Excellent!
Funny though: before my postings I went through the entire
<http://www.mozilla.org/docs/dom/domref/dom_event_ref.html#998197>
I found no mention that the global "event" object is also available in
FF, this is why I even did not try it. Strange they keep in deep secret
the only really working method. Is it only because this idea got first
contaminated by durty hands of Microsoft? :)
 
M

Martin Honnen

VK said:
event.target||event.srcElement­

Oh! Excellent!
Funny though: before my postings I went through the entire
<http://www.mozilla.org/docs/dom/domref/dom_event_ref.html#998197>
I found no mention that the global "event" object is also available in
FF, this is why I even did not try it. Strange they keep in deep secret
the only really working method.


There is no global event object in Firefox. There is an event argument
however in inline event handlers. So
<div onclick="alert(event);">
works as the onclick handler has an argument named event that is passed
in the current event object.
That is quite different from the IE way of having a global event object.
 
V

VK

Giving credits to the Mozilla team: their event tracking indeed works,
so "eventPhase is always 2" is a textual bug, not a mechanical one.

The test below shows that I really can capture events on the first
phase (up->down, capturing). This way there is no need to backtrace
bubbles on the second phase to find out the real target.
So there is no any "chaos" as I originally said. Just a bit too
over-complicated for intuitive use.

<html>
<head>
<title>FireFox test</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1">
<script>
var out = null;
function init() {
out = document.forms[0].elements[0];

document.getElementById('UL1').addEventListener('mouseout',test1,true);

document.getElementById('UL1').addEventListener('mouseout',test2,false);
}

function test1(e) {
//e.stopPropagation();
out.value+= 'V ';
}
function test2(e) {
out.value+= '^ ';
}
</script>
<style type="text/css">
<!--
/* this to prevent ul's to take
the whole page width
so you could slip your mouse from the right */
ul { width: 20%}
-->
</style>
</head>
<body bgcolor="#FFFFFF" onload="init()">
<h4>Test Case</h4>
<ul id="UL1">
<li><a href="javascript:void(0)">Item 1</a></li>
<li><a href="javascript:void(0)">Item 2</a></li>
<li><a href="javascript:void(0)">Item 3</a></li>
</ul>
<form>
<textarea cols="50" rows="4"></textarea>
</form>
<p>&nbsp;</p>
</body>
</html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top