Short-form question
I’m executing dojo.query() and applying an event handler to all of the returned nodes, using the NodeList.onmouseenter() function. However, when one of those nodes triggers the event, I need to know which one it was, so I can traverse the DOM from that particular node’s location. How can I get a reference that particular node at trigger-time?
Long-form question with full context
I am trying to adapt a jQuery-powered navigation menu (see overview and complete source) to work in a Dojo environment. In a nutshell, the HTML looks like this:
<ul class="topnav">
<li><a href="#">Home</a></li>
<li>
<a href="#">Tutorials</a>
<ul class="subnav"> <!-- This CSS class hides the <ul> on page load -->
<li><a href="#">Sub Nav Link</a></li>
<li><a href="#">Sub Nav Link</a></li>
</ul>
<span></span> <!-- CSS fills the <span> with an image -->
</li>
...
The outermost <ul> tag represents the navigation menu as a whole… and the nested <ul> tags are where a menu item has a drop-down submenu. Such menu items also have an <span> tag in there, to display an arrow image and make things easier to identify during DOM-traversing.
So, the jQuery code adds an event handler to all those <span> tags. The tutorial link above uses an “onClick“, but I plan to change that to a hover (i.e. “onmouseenter” and “onmouseleave“). Either way, the event trigger causes the hidden submenu to be diplayed with a jQuery “slideDown” effect (equivalent to Dojo’s “wipeIn“).
$("ul.topnav li span").click(function() {
$(this).parent().find("ul.subnav").slideDown('fast').show();
});
To get from the <span> to the nested <ul>, the event handler crawls the DOM one level up and then one level back down… starting from $(this). This is the part that is killing me in Dojo! I’ve tried dozens of variations, but here is my current (broken) code:
dojo.require("dojo.fx");
dojo.require("dojo.NodeList-traverse");
dojo.require("dojo.NodeList-manipulate");
dojo.ready(function(){
dojo.query("ul.topnav li span").onmouseenter(function(node) {
node.siblings("ul.subnav").wipeIn().play();
});
}
Inside of Dojo’s NodeList event connection functions (e.g. onmouseenter), I can’t figure out how to get a trigger-time reference to the node that was triggered. The anonymous function I’m passing to “onmouseenter” takes a parameter called “node“, but that’s just my wishful thinking. Dojo doesn’t really pass such a reference.
What I need is an equivalent to the $(this) on the second line of the above jQuery snippet. A reference to the particular node that was event-triggered, so that I can traverse the DOM from that particular node’s location. Is there an easy way to do this with Dojo’s NodeList that I’m just missing?
IIRC, the onmouseenter callback doesn’t receive a node as a parameter but receives an event object instead. If this is the case you can try to:
Get the node through other means, (evt.currTarget or something like that, I always get confused with these…)
Use a forEach instead, get the references to the nodes, and do the event connection manually: