Opened 4 years ago

Closed 4 years ago

#11459 closed enhancement (fixed)

live() and delegate() functions

Reported by: bill Owned by: bill
Priority: high Milestone: 1.6
Component: General Version: 1.5
Keywords: Cc:
Blocked by: Blocking:

Description

Implement live() and delegate() functions like jQuery's live() (http://api.jquery.com/live/) and delegate() (http://api.jquery.com/delegate/).

See http://thread.gmane.org/gmane.comp.web.dojo.devel/12516/focus=12559 for details. James suggested putting it into dojox/ first... I guess we would need a new query/ project as I don't see any other place to put it.

See also #11457 about fixing the NodeList.closest() performance problem. live() and delegate() both leverage closest(), so it's performance is important.

Attachments (2)

live.html (2.0 KB) - added by bill 4 years ago.
prototype of dojo.live()
delegate.html (3.6 KB) - added by bill 4 years ago.
prototype of NodeList.delegate()

Download all attachments as: .zip

Change History (8)

Changed 4 years ago by bill

prototype of dojo.live()

Changed 4 years ago by bill

prototype of NodeList.delegate()

comment:1 Changed 4 years ago by jburke

There has been some confusion in the jQuery community about how live() works, mainly that the selector involved would be available for other chainable actions or that a selection could be done, then live applied to it. I read delegate as a way to improve the performance of some delegated bindings, but it also operates more like how people expect for a chained selector API. So I suggest we just implement delegate, and do not do live. I could be missing something though, so contrary feedback is appreciated.

Putting this in dojox to bake for a bit is desirable. Things we want to consider before moving to core:

  • need an undelegate
  • As written, there are IE events like focus/blur, select onchange and some forms of form submission that do not bubble in IE. From what I have heard listening to the discussion around the jQuery version, there were some more extraordinary methods used to get those things to bubble. So I expect we either need to set the expectations correctly for what we want to provide or consider using more code to cover those cases.

Maybe we work out those kinks before the next release, and we can just move the code to core and remove the dojox thing before the release, but to give folks a chance to play with it first, let's start it in dojox.

How about a dojox/NodeList structure, and we can do dojox/NodeList/delegate.js. Traditionally, for things that modify an existing object, it would be more like dojox/NodeList/NodeList-delegate.js but that seems excessive. dojox/NodeList-/delegate.js might be a choice, too, but seems weird. I favor dojox/NodeList/delegate.js even though it breaks the convention. If we want convention, then dojox/NodeList-/delegate.js, but dojox/NodeList/delegate.js reads better.

It is a bit unfortunate that we have a dojo.delegate() that deals with JS objects and a NodeList delegate that deals with event delegation. But matching the API for nodelists in jQuery is more useful than coming up with a different name.

I will look more at the closest() issues later, hopefully tonight, but may not be until tomorrow night.

comment:2 Changed 4 years ago by bill

  • Status changed from new to assigned

OK, I'll add NodeList.delegate to dojox for now, as dojox/NodeList/delegate.js.

About confusion with jQuery's live(): If I understood you correctly that confusion is due to live() working off of (jQuery's) NodeList, and people wouldn't be confused by a

dojo.live(selector, eventName, fn)

syntax. OTOH the above dojo.live() call be also be done as:

dojo.query("body").delegate(selector, eventName, fn)

so supporting dojo.live() is not strictly necessary. Of course all the public API's in dojo/_base/html.js are redundant with NodeList and perhaps should be dropped for 2.0.

comment:3 Changed 4 years ago by bill

need an undelegate

That would be nice but it's the same issue as NodeList.connect() losing the connection handles. If we solve that one the we get undelegate() for free.

As written, there are IE events like focus/blur, select onchange and some forms of form submission that do not bubble in IE. From what I have heard listening to the discussion around the jQuery version, there were some more extraordinary methods used to get those things to bubble. So I expect we either need to set the expectations correctly for what we want to provide or consider using more code to cover those cases.

Hmm, that's annoying. Actually focus doesn't seem to bubble anywhere. That's why dijit's focus manager uses attachEvent() / addEventListener().

comment:4 Changed 4 years ago by bill

(In [22528]) Fix/enhance dojo._filterQueryResult(), NodeList.closest(), NodeList.orphan(), and NodeList.filter() to work on descendant selectors like "div > span", yet to work efficiently for simple selectors like ".foo". Fixes #11457, #11458 !strict.

Also, enhanced NodeList.closest() to take an optional root parameter (same as dojo.query()'s root parameter). If root is specified, the selector is relative to that node rather than the document root. This parameter will be useful for future NodeList.delegate(). Refs #11459.

comment:5 Changed 4 years ago by jburke

Right, I am fine leaving dojo.live as a separate exercise, although, I suppose we could do what we do with other NodeList APIs, distill the API down to something that works without a NodeList, then use one of the adapt methods in NodeList to map it into something that works with NodeLists. In that way, supposedly dojo.live could call that method directly (or it would be that method), and it could return the disconnect handle. So those wanting a way to disconnect/undelegate/die, would have a way to do it.

The basic issue with NodeList connect and our connect architecture in general is the need to get some object back to do the disconnect. If the arguments passed to connect could be reused to disconnect (similar to how addEventListener/removeEventListener work natively), then it would be easier to support disconnect and undelegate. This is complicated by the auto-hitch support we have in connect though, it is my impression that the generated hitch function will not be the same as the one used for the connect, so it will not disconnect properly. Probably worth a test to confirm though.

comment:6 Changed 4 years ago by bill

  • Resolution set to fixed
  • Status changed from assigned to closed

(In [22534]) Initial version of NodeList.delegate(), matching jQuery's delegate() method (and unrelated to the dojo.delegate() function similar to dojo.mixin()). This checkin creates a new dojox.NodeList project which in theory could hold lots of NodeList enhancements like those in plugd. Alternately NodeList.delegate() may be rolled into core in the future, and this project deleted.

Limitations include:

  • doesn't work for events that don't bubble, like focus
  • no single node version (ie, there's no dojo.delegateEvent() function); same asthe methods in NodeList-traverse (ex: closest())
  • like NodeList.connect(), there is no way to remove the handlers setup by delegate() (ie, no undelegate() method)

Fixes #11459.

Note: See TracTickets for help on using tickets.