Connecting Tech Pros Worldwide Help | Site Map

FireFox event model failure

 
LinkBack Thread Tools Search this Thread
  #1  
Old July 23rd, 2005, 07:51 PM
VK
Guest
 
Posts: n/a
Default FireFox event model failure

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.


  #2  
Old July 23rd, 2005, 07:51 PM
VK
Guest
 
Posts: n/a
Default Re: FireFox event model failure

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>

  #3  
Old July 23rd, 2005, 07:51 PM
Martin Honnen
Guest
 
Posts: n/a
Default Re: FireFox event model failure



VK wrote:
[color=blue]
> 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)[/color]

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/
  #4  
Old July 23rd, 2005, 07:51 PM
Duncan Booth
Guest
 
Posts: n/a
Default Re: FireFox event model failure

VK wrote:
[color=blue]
> 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.
>[/color]

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)">
  #5  
Old July 23rd, 2005, 07:52 PM
Lasse Reichstein Nielsen
Guest
 
Posts: n/a
Default Re: FireFox event model failure

"VK" <schools_ring@yahoo.com> writes:
[color=blue]
> 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).[/color]

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>
[color=blue]
> On theory you can handle events during any phase on any level.[/color]

Correct, as long as event propagation isn't stopped before the event
hits that level.
[color=blue]
> 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.[/color]

Correct. The third argument is also called "capture", and the up->down
phase is called the capture phase.
[color=blue]
> 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).[/color]

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" :)
[color=blue]
> Eine Frage fuer Million Dollar: what the first phase for anyway?[/color]

The capture phase, not the bubbleing phase.
[color=blue]
> 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)">[/color]

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.
[color=blue]
> gives you undefined for e.[/color]

As it should. Nobody have declared any variable called "e".
[color=blue]
> 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.[/color]

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.
[color=blue]
> 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.[/color]

I have no idea what these failures are, but this is not the reason for
them.
[color=blue]
> 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.[/color]

Big words. Now eat them :)
[color=blue]
> 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.[/color]

<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 - lrn@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
  #6  
Old July 23rd, 2005, 07:52 PM
VK
Guest
 
Posts: n/a
Default Re: FireFox event model failure

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

  #7  
Old July 23rd, 2005, 07:53 PM
Martin Honnen
Guest
 
Posts: n/a
Default Re: FireFox event model failure



VK wrote:
[color=blue]
> I'm using build 1.0.4 - this is the latest upon mozilla.org. The bug is
> not fixed.[/color]

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/
  #8  
Old July 23rd, 2005, 07:53 PM
VK
Guest
 
Posts: n/a
Default Re: FireFox event model failure

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? :-)

  #9  
Old July 23rd, 2005, 07:53 PM
Martin Honnen
Guest
 
Posts: n/a
Default Re: FireFox event model failure



VK wrote:
[color=blue]
> 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.[/color]


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/
  #10  
Old July 23rd, 2005, 07:53 PM
VK
Guest
 
Posts: n/a
Default Re: FireFox event model failure

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>

 

Bookmarks

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Popular Articles

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over 220,989 network members.