Simon Staton
Simon Staton

Reputation: 4505

scrollIntoView() preventing other listeners from triggering

I am using scrollIntoView() on an event target to ensure it is visible in its parent which has overflow: scroll, this is mainly for accessibility reasons.

My problem is that I also have click events associated with this element and when a click event also fires the focus e.target.scrollIntoView() is preventing other events from firing.

This is my current example: http://jsfiddle.net/omhuorpr/

require([
    "dojo/query",
    "dojo/on"
], function(query, on){

    var el = query('#someElement');

    el.on('click', function(e){
        e.preventDefault();
        console.log("clicked");
    });

    el.on('focus', function(e){
        console.log("focus");
        e.target.scrollIntoView();
    });

});

If you click on the element and check the console it will only fire the focus, if you re-click it then fires the click. Ideally I want to fire both at the same time or just the click.

A simple fix that works is to move this process to the end of the execution stack via a timeout however ideally I want to find out why scrollIntoView() is preventing other events from firing.

Upvotes: 3

Views: 1270

Answers (1)

CupawnTae
CupawnTae

Reputation: 14580

It's because the focus event fires on mouse down, and the click event fires on mouse up. If the element has scrolled so that the mouse pointer is no longer over the element by the time you release the button, the click event won't fire. However, if the mouse pointer is still over the element after the scroll, the click will fire.

If you increase the font size in your fiddle and click near the top, you'll see the click fire. If you click near the bottom and the element scrolls out from under the pointer, the click event won't fire. E.g.

#someElement {
    font-size:80px;
}

http://jsfiddle.net/omhuorpr/1/

Upvotes: 3

Related Questions