Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event delegation handlers are called in incorrect order #62

Closed
phillipskevin opened this issue Mar 20, 2019 · 1 comment · Fixed by #63 or #64
Closed

Event delegation handlers are called in incorrect order #62

phillipskevin opened this issue Mar 20, 2019 · 1 comment · Fixed by #63 or #64
Assignees
Labels

Comments

@phillipskevin
Copy link
Contributor

In the CanJS 3.x-5.x, delegated events do not work correctly.

If you have a view like:

<div>
  <p>Hello</p>
</div>

...and these event handlers:

    '{element} div click': function(el, ev) {
      ev.stopPropagation();
      console.log('parent clicked');
    },
    '{element} p click': function(el, ev) {
      ev.stopPropagation();
      console.log('child clicked');
    }

...clicking on the <p> will cause both event handlers to be called.

This is happening because in this code:

canReflect.each(handlersBySelector, function(handlers, selector){
var cur = ev.target;
do {
// document does not implement `.matches` but documentElement does
var el = cur === document ? document.documentElement : cur;
var matches = el.matches || el.msMatchesSelector;
// Text and comment nodes may be included in mutation event targets
// but will never match selectors (and do not implement matches)
if (matches && matches.call(el, selector)) {
handlers.forEach(function(handler){
handler.call(el, ev);
});
}
// since `el` points to `documentElement` when `cur` === document,
// we need to continue using `cur` as the loop pointer, otherwhise
// it will never end as documentElement.parentNode === document
cur = cur.parentNode;
} while (cur && cur !== ev.currentTarget);
});

...the loop over handlersBySelector should be done inside of the do/while loop so that the inner-most event handler will always be hit first.

@phillipskevin
Copy link
Contributor Author

stopPropagation is not stopping an event from hitting a separate delegated event listener. I need to call the actual stopPropagation. Going to reopen so I can fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants