#13849 closed defect (fixed)
delegation for mouse.enter doesn't work
Reported by: | bill | Owned by: | Kris Zyp |
---|---|---|---|
Priority: | high | Milestone: | 1.7 |
Component: | Events | Version: | 1.6.1 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
The documentation lists an example:
define(["dojo/on", "dojo/mouse"], function(on, mouse){ on(node, on.selector(".myClass", mouse.enter), myClassHoverHandler); });
That's not working for me (will attach test case). The problem seems to be in the mouse.js code, in the test:
if(!dom.isDescendant(evt.relatedTarget, node))
node here is the node specified in the on() call above, rather than the .myClass node. Thus dom.isDescendant() returns true.
Attachments (1)
Change History (12)
Changed 9 years ago by
Attachment: | selector.html added |
---|
comment:1 Changed 9 years ago by
In attached test case, console.log() should fire when mousing over the gray border, but not when mousing over the numbers inside the gray border. It's not printing anything for me on IE8 or FF5/mac.
comment:2 Changed 9 years ago by
Summary: | descendant selector using mouse.enter broken → delegation for mouse.enter doesn't work |
---|
comment:3 Changed 9 years ago by
The mouseenter/mouseleave events don't bubble, and therefore are not compatible with event delegation. This is documentation bug (the example), and should be fixed.
comment:4 Changed 9 years ago by
Hmm, that's disappointing, I thought you could trivially make it work by changing mouse.js so
if(!dom.isDescendant(evt.relatedTarget, node)){
becomes
if(!dom.isDescendant(evt.relatedTarget, evt.target)){
or something like that.
If you can't use on.selector() for mouse.enter/mouse.leave it seems like you can't use it for anything, but maybe I'm misunderstanding. Anyway I'm looking forward to see your updated documentation example about when to use on.selector().
comment:5 Changed 9 years ago by
If that change will fix it, I would be glad to give to do it. I'll give it a try.
comment:6 Changed 9 years ago by
Of course, that would mean dropping the IE specific code that connects to mouseenter/mouseleave, rather than mouseover/mouseout.
comment:7 Changed 9 years ago by
I think I see what you are doing, but the purpose of mouse.enter and mouse.leave is to emulate the mouseenter/mouseleave which is a non-bubbling (and descending-only) version of mouseover/mouseout. Your fix makes the event descending-only, but does follow the non-bubbling behavior of mouseenter/mouseleave. How do use mouse.enter/leave to get only mouse entering and leaving on a specific target? For example, with your test case if I do:
on(dom.byId("table"), mouse.enter, ...
Based on the "mouseenter" behavior I would expect that to only fire an event when you hover over the table, not when any of the td's are hovered, but it fires for every element being hovered (in descendant fashion).
I suppose we could create our own event that is descending-only but bubbling, maybe mouse.into and mouse.outof. Or maybe we could have the extension type detect that it is being used in delegation and switch to bubbling for that case. Not sure...
comment:8 Changed 9 years ago by
I agree that new custom events would solve the issue, as they would allow apps to do both:
on(table, mouse.enter, myClassHoverHandler);
and
on(table, on.selector("td", mouse.in), myClassHoverHandler);
Ideally, to reduce API surface area, mouse.enter would work in both cases above. You could possibly achieve that by either:
a) Pass in a third flag to the mouse.enter "constructor" indicating whether or not it was wrapped in an on.selector()
b) Have a bubbling: false flag inside mouse.enter. If dojo/on sees that flag then it treats
on(table, mouse.enter, myClassHoverHandler);
to be something like:
on(table, on.selector(function(evt){ return evt.target == table}, mouse.enter), myClassHoverHandler);
(It probably wouldn't actually call on.selector(), but would be similar code.)
comment:11 Changed 9 years ago by
Milestone: | tbd → 1.7 |
---|
test file, console.log() should print when mouse over gray borders