Posted in Dojo Cookies
Avoiding Event Bubbling Confusion
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.
