By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,905 Members | 902 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,905 IT Pros & Developers. It's quick & easy.

FireFox event model failure

P: n/a
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.

Jul 23 '05 #1
Share this Question
Share on Google+
9 Replies


P: n/a
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('m ouseout',test,true);

document.getElementById('UL2').addEventListener('m ouseout',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>

Jul 23 '05 #2

P: n/a


VK wrote:
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.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #3

P: n/a
VK wrote:
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.


That's because it is called 'event'. Try:

<ul onmouseover="alert(this.onmouseover.toSource())">

to see what you actually get in your event handler when you put the code
inline.

Anyway, this should do what you want:

<ul onmouseover="f1(event)" onmouseout="f2(event)">
Jul 23 '05 #4

P: n/a
"VK" <sc**********@yahoo.com> writes:
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:
<URL:http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-flow>
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
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #5

P: n/a
VK
I'm using build 1.0.4 - this is the latest upon mozilla.org. The bug is
not fixed.

Jul 23 '05 #6

P: n/a


VK wrote:
I'm using build 1.0.4 - this is the latest upon mozilla.org. The bug is
not fixed.


I said "<https://bugzilla.mozilla.org/show_bug.cgi?id=245569>
this bug has been fixed in Mozilla trunk builds." so download a trunk
build and you will find that there the bug is fixed. 1.0.4 is the latest
release but not a trunk build. You can see in the bug entry on bugzilla
when it has been fixed.
--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #7

P: n/a
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? :-)

Jul 23 '05 #8

P: n/a


VK wrote:
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.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Jul 23 '05 #9

P: n/a
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('m ouseout',test1,true);

document.getElementById('UL1').addEventListener('m ouseout',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>

Jul 23 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.