Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9394 (new defect)

Opened 9 months ago

Last modified 3 weeks ago

[PATCH] [TEST] window "onload" executing before all of the "contentloaded" observers are executed.

Reported by: jdalton Assigned to: sam
Priority: high Milestone: 2.x
Component: Prototype Version: edge
Severity: major Keywords:
Cc:

Description

Part 1:

In some instances where you have a lot of observers attached to the "contentloaded" event, the window.onload event will fire before all of the "contentloaded" observers are executed.

Part 2:

All browsers, except IE, follow the "first in, first out" rule.
This means that:

$('foo').observe('click', function(){ alert('one');});
$('foo').observe('click', function(){ alert('two');});
$('foo').observe('click', function(){ alert('thee');});

//EOMB - when foo is clicked alerts: 'one', 'two', and 'three'
//IE   - when foo is clicked alerts: 'three', 'two', and 'one'

My proposed fix will address both issues (I will create a patch when I have some time).
Basically you mod the Event class to manage the observer list (instead of letting the browser).

Back to the previous example:

$('foo').observe('click', function(){ alert('one');});

/* 
1)  Event.observe checks the element for an “__eventInterceptHandle”
2)  If no handle exists it creates the handle and all the peaces necessary
    to track the observers of that Element+EventName.
3)  When foo is clicked it triggers the one “real” handler to call the 
    subsequent observers (first in first out).

When the window onload event fires it checks the status of the 
“contentloaded” observers. If they are not done executing it loops 
checking its status every 10 ms or so.
*/


Loose Examples

Here is an example of similar functionality I used in Prototype 1.5.1.
The method names are not important, the key is in the functionality.

Event Intercept code:
http://pastie.caboo.se/private/rzzrkiaa3zvhclj1uh

Cross-browser onDOMContentLoaded using Event.intercept():
http://pastie.caboo.se/private/euowdrekwczeednbzr

IE window.onResize() fix
(problem discussed here http://www.snook.ca/archives/javascript/ie6_fires_onresize/ )
, this code requires a class called "Window" but you get the point:
http://pastie.caboo.se/private/scxhidmjmwstj35slg

Attachments

event.html.patch (1.2 kB) - added by samleb on 03/13/08 00:05:49.
Corresponding unit test
event.js.patch (4.0 kB) - added by samleb on 03/19/08 14:18:14.
Patch for event.js

Change History

02/27/08 07:54:10 changed by samleb

  • summary changed from window "onload" executing before all of the "contentloaded" observers are executed. to [PATCH] [TEST] window "onload" executing before all of the "contentloaded" observers are executed..

The attached patch ensures IE event handlers calling order is FIFO and implements documentElement.doScroll technique to detect DOMContentLoaded on IE.

Test passes on all supported browsers.

03/13/08 00:05:49 changed by samleb

  • attachment event.html.patch added.

Corresponding unit test

03/13/08 00:08:48 changed by samleb

I just updated the patch so that it ensures all stylesheets are loaded before firing dom:loaded (Opera issue).

03/19/08 14:18:14 changed by samleb

  • attachment event.js.patch added.

Patch for event.js

04/09/08 02:39:31 changed by jdalton

Very good work :), I saw the stylesheet fix in jQuery and was wondering why Prototype didnt do it.

I do have one question. why use wrappers.clone() in the wrappers.dispatcher method, itsn't that wasteful cycles?

Prototype team also check out (IE memory leak fix): #9466

04/09/08 02:43:10 changed by jdalton

I should also point out that only "Part 2" of this ticket has been addressed.
Part 1 still needs a patch.

04/23/08 17:37:49 changed by jdalton

fixed this in my git fork: http://github.com/jdalton/prototype/commit/29349e2efa65ecc7b6e6550729c80b4290fcd62a

fixes Part1 and Part2 along with the window resize issue. A huge thanks to samleb :)