delegate.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. define("dojox/NodeList/delegate", ["dojo/_base/lang", "dojo/query", "dojo/_base/NodeList", "dojo/NodeList-traverse"], function(lang, query, NodeList) {
  2. // module:
  3. // dojox/NodeList/delegate
  4. // summary:
  5. // TODOC
  6. /*=====
  7. // doc alias helpers:
  8. NodeList = dojo.NodeList;
  9. =====*/
  10. lang.extend(NodeList, {
  11. delegate: function(/*String*/ selector, /*String*/ eventName, /*Function*/ fn){
  12. // summary:
  13. // Monitor nodes in this NodeList for [bubbled] events on nodes that match selector.
  14. // Calls fn(evt) for those events, where (inside of fn()), this == the node
  15. // that matches the selector.
  16. // description:
  17. // Sets up event handlers that can catch events on any subnodes matching a given selector,
  18. // including nodes created after delegate() has been called.
  19. //
  20. // This allows an app to setup a single event handler on a high level node, rather than many
  21. // event handlers on subnodes. For example, one onclick handler for a Tree widget, rather than separate
  22. // handlers for each node in the tree.
  23. // Since setting up many event handlers is expensive, this can increase performance.
  24. //
  25. // Note that delegate() will not work for events that don't bubble, like focus.
  26. // onmouseenter/onmouseleave also don't currently work.
  27. // selector:
  28. // CSS selector valid to `dojo.query`, like ".foo" or "div > span". The
  29. // selector is relative to the nodes in this NodeList, not the document root.
  30. // For example myNodeList.delegate("> a", "onclick", ...) will catch events on
  31. // anchor nodes which are (immediate) children of the nodes in myNodeList.
  32. // eventName:
  33. // Standard event name used as an argument to `dojo.connect`, like "onclick".
  34. // fn:
  35. // Callback function passed the event object, and where this == the node that matches the selector.
  36. // That means that for example, after setting up a handler via
  37. // dojo.query("body").delegate("fieldset", "onclick", ...)
  38. // clicking on a fieldset or *any nodes inside of a fieldset* will be reported
  39. // as a click on the fieldset itself.
  40. // example:
  41. // | dojo.query("navbar").delegate("a", "onclick", function(evt){
  42. // | console.log("user clicked anchor ", this.node);
  43. // | });
  44. // Possible future tasks:
  45. // - change signature of callback to be fn(node, evt), and then have scope argument
  46. // to delegate(selector, eventName, scope, fn)?
  47. // - support non-bubbling events like focus
  48. // - support onmouseenter/onmouseleave
  49. // - maybe should return an array of connect handles instead, to allow undelegate()?
  50. // - single node version
  51. return this.connect(eventName, function(evt){
  52. var closest = query(evt.target).closest(selector, this);
  53. if(closest.length){
  54. fn.call(closest[0], evt);
  55. }
  56. }); //dojo.NodeList
  57. }
  58. });
  59. return NodeList;
  60. });