Permalink
Browse files

Merge pull request #53 from MathiasPaumgarten/events/listen

adds optional context to listen and delegate
  • Loading branch information...
2 parents f8c8066 + e8d22f7 commit a002c96f6d0e7228aa6d9e2ddc2962636b216ddd @MathiasPaumgarten committed Feb 3, 2014
Showing with 47 additions and 8 deletions.
  1. +6 −2 docs/events.md
  2. +3 −3 source/events/delegate.js
  3. +8 −3 source/events/listen.js
  4. +17 −0 tests/events/spec-delegate.js
  5. +13 −0 tests/events/spec-listen.js
View
@@ -3,7 +3,7 @@
Utilities for manipulating and observing DOM events.
-## delegate(root, selector, eventNames, callback)
+## delegate(root, selector, eventNames, callback, [context]):Object
Adds `callback` as an event listener that will listen for events that bubble
from elements that match `selector`.
@@ -19,6 +19,8 @@ selector. It will not be called when an event is triggered directly on `root`.
The first argument to `callback` will be the `Event` object and the context will
be the child node that matches `selector`.
+`context` optionally overrides the context of the callback.
+
The return value is an object that contains a `.remove` function that when
called will remove the event listener. You cannot remove the listener with
[`removeListener`](#removeListener).
@@ -35,7 +37,7 @@ delegate(container, "button.action", "click", function() {
See also: [`listen`](#listen)
-## listen(nodes, eventNames, callback):Object
+## listen(nodes, eventNames, callback, [context]):Object
Adds `callback` as an event listener to all the nodes for the specified events.
@@ -47,6 +49,8 @@ attached to.
nodes. The first argument to `callback` will be the `Event` object and the
context will be the node that triggered the event.
+`context` optionally overrides the context of the callback.
+
The return value is an object that contains a `remove` method that will remove
the listener that was added. You can also use
[`removeListener`](#removeListener) to remove the listener.
@@ -14,16 +14,16 @@ define(["./listen", "../dom/matches"], function(listen, matches) {
}
}
- function listenOn(root, selector, eventName, handler) {
+ function delegate(root, selector, eventName, handler, context) {
return listen(root, eventName, function(e) {
var target = getTarget(e, selector, root);
if (target) {
- handler.call(target, e);
+ handler.call(context ? context : target, e);
}
});
}
- return listenOn;
+ return delegate;
});
View
@@ -2,14 +2,19 @@ define([
"../utils/allNodes",
"./removeListener",
"mout/lang/isArray",
- "mout/array/forEach"
-], function(allNodes, removeListener, isArray, forEach) {
+ "mout/array/forEach",
+ "mout/function/bind"
+], function(allNodes, removeListener, isArray, forEach, bind) {
- function listen(nodes, eventNames, callback) {
+ function listen(nodes, eventNames, callback, context) {
if (!isArray(eventNames)) {
eventNames = eventNames.split(" ");
}
+ if (context) {
+ callback = bind(callback, context);
+ }
+
allNodes(nodes, function(node) {
forEach(eventNames, function(name) {
node.addEventListener(name, callback, false);
@@ -94,6 +94,23 @@ define(["cane/events/delegate"], function(delegate) {
expect(handler.calledTwice).to.be(true);
});
+ it("should call callback in context if specified", function() {
+ var span = document.createElement("span"),
+ el = document.createElement("div"),
+ event = document.createEvent("Event"),
+ callback = sinon.spy(),
+ context = { foo: "bar" };
+ event.initEvent("test", true, true);
+
+ el.appendChild(span);
+ document.body.appendChild(el);
+
+ delegate(el, "span", "test", callback, context);
+ span.dispatchEvent(event);
+
+ expect(callback.calledOn(context)).to.be(true);
+ });
+
});
});
@@ -64,6 +64,19 @@ define(["cane/events/listen"], function(listen) {
expect(callback.called).to.be(false);
});
+ it("should call callback in context if specified", function() {
+ var context = { a: 1 },
+ el = document.createElement("div"),
+ event = document.createEvent("Event"),
+ callback = sinon.spy();
+ event.initEvent("test", true, true);
+
+ listen(el, "test", callback, context);
+ el.dispatchEvent(event);
+
+ expect(callback.calledOn(context)).to.be(true);
+ });
+
});
});

0 comments on commit a002c96

Please sign in to comment.