Avoiding Event Bubbling Confusion
by Peter Higgins

There is a minor weirdness about connecting event handlers, especially events that bubble. Here I’ll explain the situation, and present a sound “fix”.

Imagine the code:

dojo.query(".someList").onclick(function(e){
	var attr = dojo.attr(e.target, "href");
	console.log(attr);
});

Nine times out of ten that will work. Especially if you have markup like:

<a href="foo.html" class="someList">bar!</a>

Though if you have more complex markup, like:

<ul class="someList">
	<li><a href="foo.html">bar</a><p>hi!</p></li>
</ul>

And run the above query, if the user clicks outside of the <a> element for whatever reason (in any CSS margins or padding), the event will bubble to the UL, and e.target will be an <li>, which doesn’t have an href.

This scenario is similar, with multiple connections:

<a href="foo.html" class="someList">Foo, <span>BAR</span></a>

If the use clicks the BAR, e.target is a <span>

A good safe way around this: save a reference TO the node you are going to connect to, and just use dojo.connect within a NodeList.forEach loop (closures, ftw):

dojo.query(".someList").forEach(function(n){
 
	dojo.connect(n, "onclick", function(e){
		if(e.target == n){
			// this node is exactly the node we're looking for, guarenteed
		}
	})
 
});

We don’t really even need to check e.target in the inner onclick, and can reference ‘n’ directly (provided we don’t care):

dojo.query(".someList").forEach(function(n){
	dojo.connect(n, "onclick", function(){
		dojo.style(n, "visibility", "hidden");
	});
});

… and not have to worry about the inner markup of .someList causing our callback only to focus on the original node we care about.

This entry was posted on Sunday, March 15th, 2009 at 11:54 pm and is filed under Dojo Cookies. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Leave a Reply

You must be logged in to post a comment.