Dojo/on and the capture phase

2019-06-24 02:18发布

问题:

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);