etamponi
etamponi

Reputation: 23

KnockoutJS: Handle event capture phase

Let's consider the standard way to bind a generic event to a ViewModel method using KnockoutJS:

<div data-bind="event: { mousedown: handler }"></div>

This code will add handler as a listener on the mousedown event to the <div>. As any other handler, it is attached to the target and bubble phase of the event.

However, I don't see a way of attaching a handler to the capture phase of an event without resorting to a manual call to addEventListener outside of the MVVM pattern provided by Knockout JS.

Is it possible to bind an handler to the event capture phase using data-bind in Knockout JS?

Upvotes: 1

Views: 1023

Answers (1)

Roy J
Roy J

Reputation: 43899

When you need to do DOM manipulation that an existing binding handler doesn't do, you write a custom binding handler. Here's a simple demonstration of a capture-phase event handler. You'll have to look at the debugging console to see the output.

ko.bindingHandlers.captureEvent = {
    init: function (element, valueAccessor) {
        var arg = valueAccessor();
        for (var eventName in arg) {
            element.addEventListener(eventName, arg[eventName], true);
        }
    }
};

vm = {
    handler: function (event) {
        console.debug(event.currentTarget.id);
    }
};

ko.applyBindings(vm);
#d1 {
    background-color: red;
    height: 35em;
    width: 35em;
}
#d2 {
    background-color: green;
    height: 25em;
    width: 25em;
}
#d3 {
    background-color: blue;
    height: 15em;
    width: 15em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div id="d1" data-bind="captureEvent: {mousedown: handler}">
    <div id="d2" data-bind="captureEvent: {mousedown: handler}">
        <div id="d3" data-bind="captureEvent: {mousedown: handler}"></div>
    </div>
</div>

Upvotes: 4

Related Questions