The window.onload Problem - Really Solved!

The window.onload problem has been proclaimed solved before but I've had issues with the brittleness of the proposed solutions due to browser sniffing and dependency on non-standard behavior. Even if the sniffing and hacking are accepted the problem has never really been solved anyway. I've been seeking a robust solution to use unobtrusive JavaScript techniques and I think at 4 am this morning I discovered one. I don't know why these things have to happen at 4 am but I do know I'd rather be sleeping.

In my previous window.onload article I looked at four techniques: bottom script, Dean Edwards, DOM polling and global delegation. Each had problems.

The first three techniques (bottom script, Dean Edwards and DOM polling) share a common fault. When the page is loaded, there is a period of time where elements are left "exposed". By exposed I mean the elements are visible and the user can interact with the elements but event handlers have not yet been attached. This period of exposure is short for most documents and that is why these techniques have worked acceptably for many developers. However the fact that there is exposure means the solutions are not as robust as using old-fashioned inline HTML event attributes. So regardless of implementation, these three techniques are not solutions.

In the comments to my previous article, Jesse Rudderman pointed out the above flaw with the first three techniques. He suggested

How about taking advantage of event bubbling instead of trying to attach an event hander to the element in time? That is, add a global onclick handler and look to see if event.target or event.originalTarget is one of the elements you're interested in. For hover effects you can do the same with onmouseover.

After his comment, I updated my previous article to look at a possible implementation and implications of his idea. With a roll-your-own event system Jesse's idea completely solves the problem for bubbling events. But what about those non-bubbling events?

I give up. I do some real work. Months pass...

Then yesterday I came across Brandon Aaron's Live Query plugin for jQuery. I'm not very familiar with jQuery but his idea is very interesting. With his plugin you can write the following unobtrusive JavaScript.

$('input[type="text"]').livequery('focus', function() { 
    alert('a text input has been focused');
});

If a new text input is added to the page using the jQuery DOM manipulation functions, then Brandon's plugin will attach the focus handler. How cool is that? This is part of the total unobtrusive JavaScript solution. This provides something similar to Internet Explorer's CSS expressions but Brandon's solution is a whole lot better. But the picture isn't complete. Those input[type="text"] elements still sit exposed during the page load as jQuery uses the Dean Edwards technique.

For non-bubbling events the event handlers must be attached to the elements themselves since there is no option for delegation. In order to attach the handlers the elements must be parsed and in the DOM. If they are in the DOM that means they are likely visible and hence exposed. It seems like an insoluble problem.

Usually before an element is focused, a bubbling event occurs (e.g. keypress, mousedown). When the Edwards technique says "go", jQuery runs a function called jQuery.ready(). This function could be run each time one of these bubbling events occurs that might precede non-bubbling event. Then the non-bubbling event handlers will be attached to the appropriate element when the non-bubbling event fires an instant later. It turns out that in Internet Explorer a user can tab to an input without a keypress event firing. So that idea out the window.

Then I think, "Ok, I'll use Jesse's solution for all bubbling events and for the very few non-bubbling events I use, I'll just use inline handlers."

And then the gears in my head (that apparently desperately need some grease) finally compute 2 + 2.

Have you read Dan Cederholm's Bulletproof Web Design? You really should. It is an outstanding example of a tutorial-type text book. Dan believes in separation of content and presentation. No border or align attributes in his HTML. That's the job of CSS. It must have tormented him that he couldn't find a way to use CSS to "null" the cellspacing attribute. I bet he tried at length. So what did he do? He compromised purity. For every table I've written since I read Dan's book I've followed his advice and started with

<table cellspacing="0">

CSS padding can then be used to give the same presentation of other cellspacing values. This compromise in allowing one thing presentational in his HTML allowed Dan to write robust pages and enables all real control in the CSS. I've used this so much that I just think of a table tag name starting with an indivisible string of 21 characters.

For the troublesome non-bubbling events, we can do the same thing Dan did. If a developer is using jQuery, the jQuery.ready() was written so it can be run multiple times and this is all bundled up with event delegation for bubbling events and Brandon Aaron's plugin for the non-bubbling events we can write pages like this

    <script type="text/javascript">
      $('input[type="text"]').livequery('focus', function() { 
          alert('a text input has been focused');
      });
    </script>

</head>
<body>

    <input type="text" focus="jQuery.ready(event)" blur="jQuery.ready(event)">

Now the text input is never left exposed. I probably wouldn't ever need the blur attribute above and I probably would only include the focus attribute in cases where I know I will be attaching focus handlers to an element. One way to think of this is it forces the bubble that otherwise wouldn't happen. We can attach as many focus handlers as we want and the roll your own event handling system can take appropriate action. As a practical backup, in case you are worried that one of these attributes may be forgotton and hence leave the element exposed indefinitely, an optional bottom script, DOM polling, the Edwards solution and the actual window.onload event could call jQuery.ready().

Because of Brandon's post I've been thinking in terms of jQuery. Instead of jQuery.ready(event) you could create a function called bubble(event) or whatever you like.

Summary

The bottom script, DOM polling and Dean Edwards solutions trade a (potentially long) period of broken UI functionality for the ability to program in the unobtrusive style. To me that weights a programmer's stylistic desires too much compared with a properly working UI.

My suggested solution trades a minor impurity in programmer ideals for an always functional UI. It's an "if you can't beat them, join them" solution. It's a compromise but like Dan Cederholm's compromise it is fixed string of attributes that is tacked on without any thought. It may be a challenge to build an efficient implementation of this solution but there is no hacking based on brittle browser features and no exposure. This solution depends only on documented browser features and behavior. That's a compromise I can abide.

Comments

Have something to write? Comment on this article.

Dean Edwards August 24, 2007

One problem is that jQuery (and other behavioral solutions) is based on CSS selectors. For some selectors you need a full DOM before you can find matching nodes, e.g. li.menu:last-child.

Peter Michaux August 24, 2007

Dean,

Thanks for the heads up. For the example you give, if that distinction is critical, fortunately it's quite easy to work around by using a class attribute of last on the last element rather than using the pseudo selector :last-child. This is the current reality with CSS because IE doesn't support the pseudo selectors. I'm no to sure this selector style of JavaScript is as general purpose as the jQuery folks think but I'm experimenting with the style.

Jim Marion August 25, 2007

Dean,

jQuery supports XPath and custom selectors as well. See http://docs.jquery.com/Selectors.

John Resig August 27, 2007

I've never seen this "exposure" that you're talking about - and I (and hundreds of thousands of jQuery users) have been using the "Dean Edwards" technique for a long time. Is there a particular browser where you see this delay occurring?

We've located one case that tends to cause problems in IE, related to changing the innerHTML of an element inline (not in the head) - and only on slow machines, and only randomly. But other than that, things have been rather uncomplicated.

Peter Michaux August 27, 2007

John,

If a page is loading and there is a network stall, then the initial chunk of HTML can be displayed but the Edwards technique will leave the page exposed. This problem points out the technique is not a complete solution to the problem. The great thing the script has done is allow people to explore the unobtrusive style because the technique does usually work.

My main concern is that the technique is based on counter-standards behavior and should break with new browsers. Imagine being the manager of a site with 150 000 lines of legacy JavaScript with code life expectancy of three years. Over a three year period, modernize that code base and on every page at least partly depend on the Edwards technique. Then imagine that the Edwards technique breaks and three years of code is not working. You can fallback on window.onload but all of a sudden you have long exposure which was exactly what was trying to be avoided. Then imagine explaining to the boss the code is based on what at that point will clearly appear to be a hack and the only reason you chose to use the hack was so you could program in a particular style you happen to like.

Now that I'm exploring efficient implementations of the delegates system I'm amazed at how fast it can be. The delay on an event seems to be only up to ~10ms with ~100 delegate "behaviors" of different event types and doesn't change with the size of the document. Using delegates allows all types of events to go through capture (even on IE) and bubble phases. It allows for controlling the order that handlers run instead of the random order the browser supplies.

Now I'm trying to determine if programming in the behavioral style is what I want to do and can be applied widely or even exclusively in a maintainable way. Any suggested reading?

Dean Edwards August 27, 2007

Any suggested reading?

http://del.icio.us/9jack9/becss

Diego Perini September 12, 2007

I believe Peter is correct, there are times where elements MAY remain exposed even for long time (depending on how bad the page is), but I also agree that those cases are really few in practical use cases. This is going to change soon, as more elaborate DOM projects and WEB applications will need more responsive UI and Events.

However, it seems to me that Brandon "LiveQuery" method will still leave elements exposed, at least for the time to execute a very heavy selector match (let say just few hundreds milliseconds for now OK!!!), but it also needs an underlying collection of tools that makes everything load and run slower.

Also I am not sure how Brandon handled the need of an onload method. However I believe his code is still bound to execute after the page is complete or the selectors wouldn't work.

The method is usable to some extent, but will very soon slow down the event processing queues, browser refresh will start to be jerky at best as explained by Brandon himself, I don't want to talk about edge cases with "mousemove", "mouseover/mouseout" are enough to bring them down. With "onclicks/keydown" things are slightly better though.

As Dean pointed out in another thread we should all listen to what "liorean" has to say on event delegation. What we really need is a good and fast Match(element, selector) method as described in his post, not a full sized selector engine.

We don't always need a nodes collection matching the selector to see if the element match. That's a slow approach.

I have had a brave but very rough implementation for a while. As I already wrote to Peter it only does well for ID, TAG, CLASSNAME and ATTRIBUTES (including ancestors) by hacking up Simon Willison getElementsBySelector and stripping the fat out.

So in my proposed solution I am missing all the child, nth, prev, next, stuff of these marvelous libraries but with them I found my method being too slow.

I tested with Dean cssQuery (fastest), jQuery and mootools which I found to work, but it seems to me DomQuery/LiveQuery still fail in the simple "table#test td" case (I may be wrong...).

What I am doing in my proposed solution is:

appendDelegate( selector, event_type, function, [delegated_element] )

Then in the main Delegate handlers loop, where each queued function is executed, I check if the target element or some of it's ancestors match the passed selector, if true the handler is fired.

  • I don't need any library to do this, just a good Event Manager
  • I can start attaching the events without having to wait load events
  • If elements are added later on, events are attached automatically
  • given the above all this is cross-browser compatible (tested)

I see many people are now approaching these method, everybody have cleverly made their homeworks...wonderful, we just need to piece together this puzzle.

Peter Michaux September 13, 2007

Diego,

a week ago I was playing with fast selectors. I just rearranged my code to do what you want for the element-selector matcher. What my code does is compile a CSS3 selector into a JavaScript function that takes one element as the argument and returns true of false if there is a match.

For example

.fooClass:nth-last-child-of-type(2)

becomes

function(element) {
    var batch = (new Date()).getTime() + "_" + Math.random(),
    e = element;
    var count = 0,
    el = e;
    var tn = e.tagName;
    if (batch != e.parentNode._FORKbatch) {
        var els = e.parentNode.childNodes;
        for (var i28 = els.length; i28 -- ;) {
            if (els[i28].nodeType == 1 && els[i28].tagName === tn) {
                var c = ( ++ count) - (2);
                els[i28]._FORKflag = (c === 0 ? true: false);
            }
        }
        e.parentNode._FORKbatch = batch;
    }
    if (e._FORKflag) {
        if (e.className && e.className.match(/(?:^|\s+)fooClass(?:\s+|$)/)) {
            return true;
        }
    }
    return false;
}

css selector match test

I just threw this together and I don't know where the bugs are :) The general technique should be about as fast as fast can be.

What are you planning on doing about non-bubbling events?

Diego Perini September 13, 2007

@Dean,

in what I am proposing we don't need to find matching nodes, we just need to check if the element that generated the event matches a given selector. If the element has not been parsed yet (ex: page not completely loaded) it can not generate events. When the node will be loaded or appended/inserted in the DOM it will react to the events we attached to the selector for it. We can still check for this kind of complex selectors "li.menu:last-child", if we can do it fast enough, however my proof of concept doesn't need to go so far... Dean this should be old stuff for you seen the fastest IE selectors implementation I have seen to date....This is a cross-browser solution (some limitations due to lighter selector engine).

@Peter,

you have completely focussed my need in this matter and a quick look to what you have posted above let me believe the method will be good. Let me put some test online so you can see this concept at work and I can test the speed.

I would really like to solve also for non bubbling events, I have a couple of ideas. However I knew from the start there will be some limitations with this solution. Now let see how far we can go. I will first concentrate in correcting some bugs with my current selector engine and see what method achieve better performances. I would say I am already at a very good point, but being a dumb ass programmer I asked your help.

I like very much jQuery concise syntax but I still believe the "$find " method is slow by concept for this implementation. John...it is still the fastest between the working selector engines, don't worry...this is completely another method similar to Behaviors but not quite like it. It has improvements over it but it will not do all of what Behavior does at least not syntactically (not yet).

The other option we have to evaluate is: instead of passing a selector, we would be passing an object with the properties/values we want to check:

({
id: 'test',
className: 'test',
nodeName: 'table',
younamedit: '100px'
})

For speed concerns, the above was the way I would like to extend my concept before giving a try to selectors. Now after seeing your "match.js" I understand that also complex selectors can yeld good results. Peter, thank you again for writing that on specific request, I hope I can give back to FORK in some way...

As soon as I can, I will have samples online with your "FORK.match" instead of my bad hack on Simon Willison good code. You will find the new tests at the end of the test cases list, I will also include duplicated test cases for Dean cssQuery and John jQuery...

At the moment, only my original NWEvents Delegate tests are available online, see here:

NWEvents

and click on the "Event Delegate" test case at the bottom.

Diego Perini September 13, 2007

Ok, the tests are online, just tell me what I am doing wrong with the selector I am using... I should tweak the original demo to make things to apparently work... ;-)

I cannot make "table#test td" work in your match, but that does not work in DomQuery either so I believe there is still some bug there. I should change the selector to just "td" to see all the cells highlighted. I changed the order of parameters in your match code to fit my needs in these tests, (element, selector).

In cssQuery/jQuery it takes too long but time does not matter here, and the reason they take to long is because they first collect all the nodes matching the selectors, which is not needed in our implementation. So move the mouse slowly on the "X"...

However I bet both Dean and John can extract a faster Match(element, selector) from their current project. My only purpose with these test was to show that this is doable and work as expected in all frameworks.

Your sample code is good enough to also convince me that this can be done with selectors, and letting the most complicated options out I hope will give us acceptable speeds in most situations.

To give you a hint about why something is wrong with match, you will see that in my code I am doing also ancestors, I mean if an ancestor match we will also need to return true. Hope it helps.

This is not a benchmark...I may have failed to write the selectors, and I may have failed in using the wrong methods in these libraries.

Peter Michaux September 13, 2007

Diego,

What I notice, and didn't think of before, in your example with my match function is there is no use of the CSS selector cascade and specificity. This is noticeable where the first set of "x" elements are supposed to have a yellow background but have a blue background.

The API could be made to look even more like CSS

NW.Event.appendDelegate('table#test td', {
    mouseover: function() {this.style.backgroundColor="yellow";},
    mouseout: function() {this.style.backgroundColor="";}
});

The "one shot" remove delegate is not working in the example because the important line is commented. (If I click the buttons multiple times I see multiple alerts.) Even if it was working and if my brief look gave me an idea of what you are trying to achieve, I don't like the idea of being able to make a particular element exempt from a behavior if it still matches the selector. I think it would be better to make the element no longer match the selector in some way. If the CSS specificity and cascade is used then a new class name could be added to the element and a later "appendDelegate" statement could override the "one-shot" behavior.

Peter Michaux September 13, 2007

I'm not advocating using CSS selector specificity and cascade because that implies only one handler for each event type. There are other ways to make those first x elements in your page yellow. Instead of directly changing the background colour you could change class names and then the real CSS cascade can change the background colour.

Diego Perini September 13, 2007

@Peter,

Sorry to have confused you with that line commented out and a typo error. I didn't want to remove the "click" only from one button, what I wanted was to remove the selector completely from the chain, so only one click on any of the button will unregister the behavior as you where suggesting. I deleted the comments, now the removeDelegate is executed.

Thank you for noticing that, and again sorry for the confusion.

I am still not introducing any logic in the examples just testing the selectors with my Delegate implementation. I really like the CSS syntax as you have depicted it above. It is much more concise and easy to read.

If you think that YUI is setting up a polling interval to check for when an element is available to attach events to that element, you will quickly see the benefits that such a method is introducing, and not only for YUI.

Did you realize that this method is fully cross-browser and that new inserted elements will acquire functionality without having to wait for it's presence and without adding new handlers to the chains ?

Peter Michaux September 13, 2007

Diego,

Yes there are big benefits to a delegate system for bubbling events. It is possible to implement capture in IE and control the order of the handlers (not that you should want to I think). I am curious about your plans for the non-bubbling events. Really they are the only trick remaining and is why I wrote this article.

Diego Perini September 14, 2007

@Peter,

NWEvents already implements re-ordering of events if that was what you mean. It is also possible to apply several delegates to the same selector, keeping in mind that we use FIFO registration so the last registered function wins.

You wrote:

If a new text input is added to the page using the jQuery DOM manipulation functions, then Brandon's plugin will attach the focus handler. How cool is that? This is part of the total unobtrusive JavaScript solution.

If this is enough for the non-bubbling situations you are talking you can do that with my NWEvents too. Have you seen the complete example, the "input" boxes at the bottom ?

I used an "mouseover" to autofocus the input boxes and change their background color, and as a more elaborate test I added a second selector rule that makes the input boxes "lightblue" when they contains the value "50". As you see this is very dynamic. If you write "50" in the other boxes you also get the same behavior if you "mouseout/mouseover" them.

I still don't understand why in Brandon solution there is a need to wait for a bubbling event to attach a non-bubbling event to finally do some checking on some field.

If I understand correctly and this is the problem you are referring well, you should solve this with a combination of "onmouseup+onkeyup" Delegates on the input elements. This will also take care of when you are landing on an input box with the TAB key. This will work in Brandon solution too.

As I said before Brandon solution will still leave these elements exposed, because he cannot attach the events before an "onload" event has notified about the page being complete. My solution does not require this because it attaches events to the root element ("documentElement") which does already exists when your scripts start executing, no way for failures.

Ok...How to for the non-bubbling events. You see, I don't want to escape your question because it is useful to have too.

From what I understand we are only talking about 2 specific events, "focus" and "blur". For "load" and "unload" I don't see the point.

  • we could use use "DOMFocusIn/DOMFocusOut" on W3C browsers and "onfocusin/onfocusout" (these events have a bubbling phase)
  • we could use "onactivate/ondeactivate" on IE and the Mutation Event "DOMActivate" on recent W3C browsers (I believe these also have a bubbling phase), they are used to get notified when the active element changes (I believe this is bound to CSS "active".
  • we have CSS pseudos like "target", "active", "focus" and "hover" which can behave like events if we can Match those properties.

Of further interest, the W3C specs states that however the "focus" and "blur" events are only dispatched after the focus is applied/removed from the element itself. The "DOMFocusIn" or "DOMFocusOut" events are dispatched after the focus or blur event have fired on the element.

Cheers

Diego Perini September 14, 2007

I have setup a quick example of how to catch the focus/blur with Delegates and still not use an "onload".

I don't know if this fits as a "total solution" however in the comments above I depicted other approaches to this specific problem you mentioned that may work better and more concisely.

Here is the link to the FOCUS/BLUR example I had in mind, a bit overcomplicated but....

Focus/Blur Example

Diego Perini September 14, 2007

Peter,

the FORK.match works ok now and is fast. It was another typo error of me.

Actually FORK.match was not used, the internal simple match was used, and that one does not do ancestors. I was debugging my code to see what was wrong and I found the error.

I was testing for FORK.match presence in this way:

if(typeof FORK 'object' && typeof FORK.match'object')

instead of:

if(typeof FORK 'object' && typeof FORK.match'function')

So dumb me...I corrected the tests. Again sorry for that.

Peter Michaux September 15, 2007

Diego,

An element may be focused by JavaScript and so there is not also a mousedown or keyup event. My guess is there are browsers from the last few years that don't support the DOMFocusIn or onActivate events. Form submission events are supposed to bubble but they don't at least in my Safari. I get the feeling that some other bubbling events may not bubble under certain conditions due to bugs.

Suppose that all this is solvable (which it is at least one way with the forced bubbling I propose in this article.) I am now considering whether or not this behavioral style is a good and/or appealing general-purpose style for browser scripting. It is good in some cases; however, the moment multiple elements on the page interact on an event it doesn't appear to be very elegant. This system of delegate handlers ends up being the flyweight design pattern. So when an event handler runs it must figure out which element fired it and find all related elements that must be modified. It is this "find all" part each time that bothers me because it means having partially matching id's (eg "tab21", "pane21") and/or a lot of DOM crawling with each event. I'm not totally sold.

(PS I know there is a bug in my match demo code I posted when there are multiple comma-separated selectors and the :not() psuedo is used in one. It is not a difficult bug to fix.)

Diego Perini September 17, 2007

Peter,

yes you can focus the element programmatically in Javascript, but not at that exact time. The element is probably not there yet and however you don't have it's ID...

You can do it later if you wish, but you will have to bootstrap your code using a window.onload or a similar detection method. A timeout like in YUI or your previous onAvailable/onContentAvailable is out of discussion I believe.

For this, use my method which emulate DOMContentLoaded on IE:

ContentLoaded"

which now fully supports IE, and avoids "document.write".

In an "Event Driven" environment you can just react to user actions on elements for which you have set up some events.

I don't have to figure out which element fired the event, it will be in the "this" keyword as usual, and I don't have to crawl through anything to call the specified user function, it is just an array lookup by selector.

All the job is done in your "matcher" (in a very fast and efficient way, caching etc), and if that "matcher" where able to correctly match "focus", "active", "hover", "disabled" and other event related pseudos we could probably also improve my NWEvents implementation.

I am completely sure it is not NWEvents job to get around the still unclear W3C specs nor to fix wrong implementations in browsers, however I am more interested in the usability and the accessibility level that my code can offer to programmers, so I temporarily added a fix in NWEvents for this. I can always remove that when a solution arrives from browser vendors or form W3C.

In the weekend I have setup a second example where I have chosen to equalize the "focus/blur" as a test of what we said above and it seems to me that this is cross-browser, I tested on 4 browsers both on Linux and Windows platform and I see no difference in how they behave.

Focus/Blur Second Example

In Mozilla/Firefox, Opera, Safari and Konqueror the "focus/blur" doesn't bubble, but it can be captured, while in IE I use the "focusin/focusout" replacement which does correctly bubble up the document.

What you are proposing in your article is loosing the separation in favor of a consistent working interface. However if that exposure is the main reason you do that, I recommend you follow the W3C specs and the accessibility guidelines and suggests you use the "disable" attributed on form elements instead of registering inline HTML events on them. Then when your code is ready re-enable them and attach the events you need. This is a field application of the code purity you profess and there are no compromises.

Diego Perini September 17, 2007

The "matcher" throws errors on IE and Opera in the FORK.match example.

I corrected that on the tests online and I am sending you the patch so you can check if it applies for you. It seemed to me that the element was not passed through the "eval" for these browsers so I used a "new Function()" construct instead. I have also hacked it up a bit in my second example, now I consider it really "compiled" in a stream of "&&" conditions, however I still haven't tried with the more difficult one like the edge CSS3 cases where there is a parameter. I was just curious, and it was funny.

Werbeagentur December 10, 2007

The Window on Load Problem works - but i wait for a patch.

Luis February 1, 2008

I've been experimenting a lot and I've found much exposure in IE6 specially, also IE7. There's a big turn off when adding Google Ads like code, that relies on document.write and iframes. A combination of high-level selectors and Flash Replacement (swfobject) may break the correct domready firing too. There're sometimes that depends on the machine or the IE version. I can ensure the Dean technique is not perfect sadly. Here is my point of view.

Diego Perini February 19, 2008

Peter,

the code we talked so much about in this thread has been updated, there are not many examples yet but I am writing some more now that the code is stable enough, and non bubbling events are also fixed.

The delegation example

The above example make use of the following two scripts.

The event manager: NWEvents The CSS3 engine: NWMatcher

You will need both of them to have a full event delegation system using CSS3 selectors, however I have made so that there is also a shorter solution that does not require the CSS3 module in case of simple tasks.

The changes were targeted to being able to exclude completely the CSS3 selector engine, thus implementing the previous method of comparing a list of passed properties/values. This is also the fastest method.

I completely avoided dependencies on other packages and also many buggy native calls, this allow for less bugs and easier integration in other environment/framework, the uncompressed combo "NWEvents" and "NWMatcher" are less than 10Kb minified, probably 5kb gzipped.

The code has been sitting on GoogleCode for a while, there are as many comments as I could in those files (both files are here and SVN too):

NWEvents at GoogleCode

I believe these script can offer the complete separation and unobtrusiveness that we were out for in our initial planning, we probably surpassed them, but there is still a lot that can be done to improve this code, your help is highly appreciated, you already helped so much with the "compiled selectors" idea.

I would really like to see some comments about this technique, of course positives and negatives (preferably constructive) :-)

Diego Perini

Ariel Flesler February 29, 2008

Hi

I thought I leave the link to this jquery plugin, that hasn't been mentioned, and it is targeted to this situation.

jQuery.Listen

It has many ups, and one downside. It is light, fast, scalable and uses event delegation, doesn't need any window.onload.

The downside is that, in order to achieve that scalability, it only supports basic selectors (id or tag and/or class). It has the focusin/focusin method incorporated for blur and focus.

Cheers

Andre May 7, 2008

Well - imo there is still no perfect solution for this. With IE8 I ran into new issues.

Peter Michaux May 7, 2008

Andre,

What issues did you find with IE8?

Nano May 29, 2008

hm, i thought, this topic was gladly done. Does anybody know the actual developement?

Justin June 10, 2008

JavaScriptMVC's event delegation Controllers supports Submit, which I'm not sure Listen does. The next release will have the event delegation pulled out as a separate plugin. Of course, it only does basic CSS selectors.

Diego Perini June 24, 2008

Well, after a while working on it again I released a new improved version of the above mentioned Event Manager.

Here are the links to the latest tests:

NWEvents Delegation Test

NWEvents Capturing Bubbling Test

NWEvents can now handle capturing and bubbling on form events like focus, blur, change, reset and submit. So delegation now work on these events too, in all tested browsers. Events can be canceled before they can execute their "default action".

The capturing and bubbling phases are emulated by relaying and then propagating the events up and down the ancestor's chain.

I added dispatch/triggering of native and custom events.

I have currently removed the comments and shortened all variables to one char length. Don't blame...everything will be set back as to make it readable and documented soon.

Will try to do that some text during my vacations...well I said try...

-
Diego Perini

Michel September 23, 2008

In the conventional approach of the model 2, an event we can only assign a single function. Let us take for example The event handler OnLoad, which typically is used to screen a script, if one side completely (scripts, graphics, plugins and stylesheets) has been loaded.

The call window.onload = myscript; is okay, as long as it remains in a script. If more than one OnLoad event handler is needed, we can use the event handler is not simply invite one another

window.onload = function1;
window.onload = function2;
window.onload = function3;

It would be only the third event handler registered, as each line replaces the previous one. If more than one OnLoad event handler to be fired, we need the event handler in a function.

function start () 
{
   function1();
   function2();
   function3();
}

window.onload = start;

It will contain a problem if we are three functions on each side not want to use and leads to errors that are not defined functions.

Timmy July 31, 2009

Unfortunately the best solutions with coding come very lately or better early in the morning ;-) A long time I searched a solution for the window.onload problem. Thank you all for helping to solve the problem.

nico January 20, 2010

they happen at the late hours of night because the resistance to infinite intelligence is lower when everybody goes to sleep. Have some milk and cookies while you're up :)

Have something to write? Comment on this article.