Opened 8 years ago
Closed 8 years ago
#17145 closed defect (invalid)
event.target is the lowest leaf during event delegation using dojo/on
Reported by: | rwadkins | Owned by: | Kris Zyp |
---|---|---|---|
Priority: | undecided | Milestone: | tbd |
Component: | Events | Version: | 1.9.0 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
When we use dojo/on to delegate an event to a higher node in the dom, we're noticing that event.target represents the lowest leaf in the tree that fired the event. There doesn't seem to be a reference to the element that we selected with our selector. Looking at the source for dojo/on seems to confirm this:
return function(target, listener) { // if the selector is function, use it to select the node, otherwise use the matches method var matchesTarget = typeof selector == "function" ? { matches : selector } : this, bubble = eventType.bubble; function select(eventTarget) { // see if we have a valid matchesTarget or default to dojo.query matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query; // there is a selector, so make sure it matches while (!matchesTarget.matches(eventTarget, selector, target)) { if (eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1) { // intentional assignment return; } } return eventTarget; } if (bubble) { // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself return on(target, bubble(select), listener); } // standard event delegation return on(target, eventType, function(event) { // call select to see if we match var eventTarget = select(event.target); // if it matches we call the listener return eventTarget && listener.call(eventTarget, event); }); };
It appears that the listener is getting called with the "eventTarget" (the one I actually care about) as the execution context, but the "event" argument contains no reference to it. Please see this jsFiddle for an example (http://jsfiddle.net/gfUKZ/). While it's possible to get the object using "this" in the listener, we can't use hitch to bind the listener to our module.
I believe that event.target should equal eventTarget in this instance.
Change History (5)
comment:1 Changed 8 years ago by
comment:2 Changed 8 years ago by
What we're doiong is
on(d, "li:click", lang.hitch(this, "bar"));
which doesn't translate well to
on(d, "li:click", function(evt){ this.bar(evt, this); //obviously this doesn't have a bar method in this context });
I'm not sure why the hitch pattern isn't supported by delegation.
comment:3 Changed 8 years ago by
it would even be supportable if evt had a property called eventTarget that contained a reference to the element matching the selector.
Although, IMO, target is more accurate.
comment:4 Changed 8 years ago by
Just do this:
var _this = this; on(d, "li:click", function(evt){ _this.bar(evt, this); });
You could alternately do this:
var bar = lang.hitch(this, "bar"); on(d, "li:click", function(evt){ bar(evt, this); });
comment:5 Changed 8 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
Replying to rwadkins:
This is how events work. Try something like
and check evt.target (while clicking on a subnode of <body>)
Instead of doing this:
you should be doing:
Presumably this ticket should be closed since the code is working as designed and documented.