Is there a way to trigger an event in the capture phase (instead of the bubbling phace) with dojo/on?
问题:
回答1:
I ended up here looking for info on the predecessor of on() - dojo.connect(). For what it's worth, dojo.connect() does not appear to support event listeners for the capture phase. It works by adding the event handler to the DOM node as a field, e.g., node["mouseclick"] = ...
Since you have to use addEventListener to receive events during the capture phase, my deduction is that dojo.connect() can't do it.
What you can do is add some event listeners to a custom object on the dom node and then use dojo.connect() on those handlers.
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js.uncompressed.js"></script>
<script type="text/javascript">
function forwardCaptureEvent(e) {
var listener = this.captureEventHandlers[e.type];
if (listener != null) listener.apply(this, arguments);
}
function enableCaptureEvent(domNode, eventType) {
if (domNode.captureEventHandlers == null) domNode.captureEventHandlers = {};
var evtHandlers = domNode.captureEventHandlers;
if (evtHandlers[eventType] == null) evtHandlers[eventType] = function(e) {};
domNode.addEventListener(eventType, forwardCaptureEvent, true);
}
function logEvent(label, e) {
dojo.byId("log").innerHTML += label + " " + e.currentTarget.id + " " + e.type + " " + [ '', 'capturing', 'target', 'bubbling' ][ e.eventPhase ] + "<br/>";
}
function logCaptureEvent(e) {
logEvent("capture phase:", e);
}
function logBubbleEvent(e) {
logEvent("bubble phase:", e);
}
window.onload = function () {
enableCaptureEvent(dojo.byId("test"), "click");
dojo.connect(dojo.byId("test").captureEventHandlers, "click", logCaptureEvent);
dojo.connect(dojo.byId("test"), "click", logBubbleEvent);
}
</script>
</head>
<body>
<div id="test" style="background: darkorange; padding: 20px;">
<div style="background: gold; padding: 20px;">
<div style="background: cornsilk; ">Click me.</div>
</div>
</div>
<div id="log"></div>
</body>
</html>
So here enableCaptureEvent
and forwardCaptureEvent
are my helper functions. enableCaptureEvent
creates the custom object of capture event listeners on the DOM node that I was talking about and then forwardCaptureEvent
is used to actually receive the capture events and forward them to these listeners.
Then to use these helpers, you call enableCaptureEvent
with a DOM node and the name of the event you want to connect to. Then to connect to it, you connect to the custom object on the DOM node which I called "captureEventHandlers". This is what I'm doing in the onload
handler. I'm also doing a normal dojo.connect
to show this doesn't interfere with catching normal bubble events.
回答2:
Yes it is possible, you can use aspects. http://livedocs.dojotoolkit.org/dojo/aspect
Especially before or around ;)
Before
The module also includes a before function that provides before advice to a method. The provided advising function will be called before the main method is called. The before function's signature is:
before(target, methodName, advisingFunction);