Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#14575 closed enhancement (fixed)

event delegation: custom matching method / avoid dojo.query() dependency

Reported by: bill Owned by: Kris Zyp
Priority: high Milestone: 1.8
Component: Events Version: 1.7.1
Keywords: Cc: Akira Sudoh
Blocked By: Blocking:

Description

It might be nice for on.selector() to support custom matching functions, like:

var selector = on.selector(function(node){
    return node.parentNode == root;
}, mouse.enter);
on(root, selector, callback);

as an alternate to

var selector = on.selector("> *", mouse.enter);
on(root, selector, callback);

Mainly this is to avoid the dojo.query() dependency. I'm not sure that dojox.mobile would want to use event delegation if it requires pulling in dojo.query().

Note that it seems like there's already a stub of code for this:

// see if we have a valid matchesTarget or default to dojo.query
matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;

.. but AFAICT there's no way to trigger that code.

Change History (7)

comment:1 Changed 7 years ago by Kris Zyp

Resolution: fixed
Status: newclosed

In [27510]:

Add support for custom selector functions, fixes #14575, !strict

comment:2 Changed 7 years ago by bill

Milestone: tbd1.8

comment:3 Changed 7 years ago by bill

In [27684]:

fix missing semicolon, and join the three var declarations into one, refs #14575 !strict.

comment:4 Changed 7 years ago by bill

Cc: Akira Sudoh added

Hmm, it's strange that (at least according to your test case) the selector function needs to return the DOMNode that it was passed, rather than a boolean. Would be a bit more convenient if it could just return the boolean.

comment:5 Changed 7 years ago by bill

Resolution: fixed
Status: closedreopened

Hmm, this really isn't functioning how I expected or wrote in the description. I intended that:

on.selector(function(node){ return domClass.contains(node, "dijitMenuItem"); }, ...)

would function equivalently to:

on.selector(".dijitMenuItem", ...)

However, apparently the function supplied to on.selector() is required to trace up the DOM tree and return the matching node (if any node matches), rather than just returning a boolean about whether or not the specified node matches.

Apparently the function I really want to specify is matchesTarget(). Akira showed me this code to do it, but it's quite complex:

var _self = this, matchesTarget = {
    matches: function(node){ return domClass.contains(node, "dijitMenuItem"); }
}  ;
on.call( matchesTarget , this.containerNode, on.selector("", mouse.enter), ...

The problem be seen shown by checking out [28210], and in _MenuBase.js changing ".dijitMenuItem" to function(node){ return domClass.contains(node, "dijitMenuItem"); }. Moving the mouse in dijit/tests/test_Mouse.html towards the middle of "File" and clicking it won't open the submenu.

Kris, what do you think?

comment:6 Changed 7 years ago by Kris Zyp

Resolution: fixed
Status: reopenedclosed

In [28489]:

Switch the selector function to act like a matches function, fixes #14575 !strict

comment:7 Changed 7 years ago by bill

In [28492]:

custom selector method no longer needs to return the node, so simplifying unit test, refs #14575 !strict

Note: See TracTickets for help on using tickets.