Friday Dec 05, 2008

Reglib gets support for submit / change / select / reset event delegation

Anybody who's ever implemented or used event delegation knows first-hand the bitter pain of IE's lack of bubbling on those events. Bitter, bitter pain.

Well, the reglib trunk has just received experimental beta support for those events. The technique is of course to co-opt other events that \*do\* bubble, and that are almost certain to be executed prior to the non-bubbling event. Within the co-opted, bubbling event, the non-bubbling event handler is added.

The fly in the ointment is the "almost" in the above phrase, "almost certain." At the very least, these events can be triggered programatically, without any prior events firing. But I thought what the heck, might as well build it and see how useful it is in the real world.

Of course many browsers do support bubbling on these events, so they get reglib's natural event delegation. Although I'll probably need a more sophisticated test, if(document.all&&!window.opera) seems a bit crude, but I wanted to get this into the trunk and in front of people. I'm sure I'll wake up in a cold sweat tonight and realize I need to recode the whole darn thing.

Here are the new methods:

reg.submit(selector,function);
reg.reset(selector,function);
reg.select(selector,function);
reg.change(selector,function);

More info: all reglib posts, reglib feed, download reglib


Update: So far the results are pretty promising, better than I had hoped even. Early iterations of the code were a bit unweildy and bug-prone, then I had an epiphany and about 90% of the code and complexity evaporated, leaving a solution that seems pretty tight, altogether.

Basically, it sets up reglib's existing delegation on the fly, directly on the element that receives the non-bubbling event. E.g. for the change event, it more or less does reg.focus('select',setDelegationOnThis) to ensure the delegation gets set up prior to a change event. Of course this is only done on IE. Everything bubbles normally for modern browsers. They are quite boring, those modern browsers.

Monday Dec 01, 2008

reglib 1.0.6 released

UPDATE: I've removed reg.pause() and reg.resume() from the trunk. Sean Hogan makes a good point in the comments below. Plus, now that reglib is doing delegation on form events, things get complicated maintaining the pause/resume system alongside the branch of code that simulates bubbling for form events in IE. One can still easily disable an event by using a selector like this: "body.on a@href" and then adding/remove 'on' from the body classname as necessary.


reglib has reached 1.0.6. Updates include:

reg.pause() and reg.resume() follow a similar pattern to reg.removeEvent():

// handle hover on all links
var hoverLinks = reg.hover('a@href',function(e){
    // handle mouseenter
},function(e){
    // handle mouseleave
});

// stop handling hover on links
reg.pause(hoverLinks);

// resume handling hover on links
reg.resume(hoverLinks);

More info: all reglib posts, reglib feed, download reglib

Saturday Nov 15, 2008

reglib versus JQuery

Read the reglib tag trail for more about reglib, or subscribe to the feed of all things tagged reglib.

Let me first of all stress that I'm not trying to bust on JQuery here. JQuery does something that needs to be done, and it does it just about as well as can be done given the tool-set browsers have collectively placed at our disposal.

With that said, I'm going to go ahead and pimp the reglib way of doing things, by which I mean declarative, over the load-traverse-modify methodology, which JQuery makes so easy.

The demo page linked below has two identical interactive widgets; one wired up using JQuery, and the other wired up using reglib.

» Demo Page «

The page is rigged like a science experiment, with a control followed by several tests in which you observe differences in behavior between the two widgets in response to various stimuli. The goal is to demonstrate reglib's resilience under duress (as it were). Enjoy.

Monday Nov 10, 2008

reglib JavaScript Library Now Available Under MIT License

The reglib is now published to Google Code and available under the MIT license.

Project Home: http://code.google.com/p/reglib/
Download: http://code.google.com/p/reglib/downloads/list

The backstory - Almost a year ago1 I made all kinds of big talk about releasing a JavaScript lib I was developing for sun.com. This library obviates (some of) the need for what I call the load-traverse-modify methodology of unobtrusive JavaScript:

  • Load: make it your business to know when the DOM has loaded.
  • Traverse: use a query to scan said DOM, returning a list of elements.
  • Modify: attach event handlers to, and otherwise manipulate, those elements.

Although LTM is quite common in JavaScript development, I believe it's an antipattern. The reglib tries to get closer to the CSS way of doing things: declare what kinds of elements get what behavior, and have that declaration take immediate effect at a global level, regardless of subsequent mutations to the DOM.

// JAVASCRIPT CODE:
reg.click("a.popup", function(e){
    window.open(this.href);
    return false;
});

/\*
ENGLISH TRANSLATION:
I declare, forthwith, that all clicks on <a> elements with
class "popup" shall be handled thusly...
\*/

So there you have it. Feel free to check it out (just check it out or actually check it out), read the documentation wiki, download, leave comments, etc. The lib also has a bunch of convenience functions for DOM manipulation, plus it has tools for doing LTM stuff because let's face it, sometimes there's no other way.

(Previous posts on this topic can be found here and here.)


1 It took so long because, in a nutshell: 1) Sun has an open source review process, you can't just release code willy-nilly, 2) During the process, I failed to be a squeaky wheel, and in fact the lawyers waited on my responses as much as I waited on their responses. However development over that interval has been constantly active, and reglib is being used on sun.com.

Monday Feb 11, 2008

A Look at Sun.COM's New Event Delegation Library

(A followup to my last post.) We're on the brink of releasing a new JavaScript mini-library to sun.com, which we call the reg library. It provides an object named, naturally enough, reg. It stands for register. With it, you can register behaviors, like this:

reg.click('ul.foo > li > a.bar', myFunction);

Once that bit of code runs, regardless of whether the entire DOM has finished loading into the browser, click events on elements matching ul.foo > li > a.bar will be handled by myFunction, which is passed a reference to the active element and the event object. This happens without any DOM traversal, and without any events ever being attached to any <a> elements. Even if the entire contents of document.body are subsequently overwritten by innerHTML, all those new element nodes implicitly inherit the correct behavior. No re-walking of the new DOM subtree ever occurs. No re-attachment of events ever occurs.

How is this even possible?

Two facts conspire to make this feasible. 1) The <body> (document.body) is available almost immediately. 2) Most events bubble. All you need to do is to stand on document.body, and you're privy to almost every event that occurs on the page, right out of the gate. No need to go seeking out the elements you need, they literally bubble their way to you. All you do is grab the event's target and ask the question, does this element, or one of its ancestors, match 'ul.foo > li > a.bar'? If so, run the associated function, if not, ignore it. This is really just event delegation, and it's nothing new, but we've made little use of it on Sun.COM before now.

Limitations, caveats, dangers

I harbor no illusions this is a perfect solution. There are limitations. Besides the fact that not all events bubble, much of time, behavior depends exclusively on preprocessing, especially if you're doing progressive enhancement. You don't want non-JS users to see useless expand/collapse signs or widgets laying around, so you build the widgets only if scripting is enabled. And the only time to build the widgets is onload. And the only way to build the widgets in the right place is... \*sigh\* traversal. Some of this can fortunately be avoided by relying as much as possible on CSS and making your widget styles depend on a dynamically-added class name, such as body.jsenabled, so there's some workaround potential at least.

There's also an inherent performance limitation. Sitting in the driver's seat on document.body isn't always a relaxing cruise through the countryside. It can easily turn into rush-hour gridlock, with a flood of events each demanding to be checked. For that reason, I dare not use this technique to handle mousemove events. That would cause a veritable torrent of events. Even mouseover events are iffy. We have the capability and it appears to work reasonably well, but time will tell whether it's really viable. Click events, on the other hand, because of their relative infrequency, are a good candidate. Of course, as we develop this thing further, we'll be looking for ways to mitigate performance risks.

So there you go

It isn't live yet, but hopefully will be soon. After this code has been chugging away out there in the wild and woolly world of production Sun.COM for a while, I may post more about this, what works, what doesn't, unexpected wins and losses, etc. Stay tuned.

About

My name is Greg Reimer and I'm a web technologist for the Sun.COM web design team.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today