When a mousedown and mouseup event don't equal a click

筅森魡賤 提交于 2019-12-21 09:17:45

问题


I've been using some buttons for a while now that have a depressed effect as they are clicked using position relative and a top: 1px in the :active pseudo-class.

I had problems with click events not firing and it turned out to be due to the mousedown and mouseup events not firing on the same element. I did a bit of fiddling to make sure the inner-most element covered the whole button and discovered that the issue remained.

If I click right at the top of the text then the link jumps down (firing the mousedown event) and then back up (firing the mouseup event) but the click does not occur. If I click nicely in the middle of the text or nicely away from the text all is fine.

The only thing I can think of here is that the mousedown event is firing on the textNode and the mouseup is firing on the anchor element as as the textNode is no longer under the cursor. Catching the event objects and looking at the targets using firebug indicates this is not the case but I really can't think of another explanation. Reading around a bit I can find some mention of events firing on textNodes in Safari but nothing about this mismatch.

The following snippet should allow you to replicate the problem. Remember, you must click right at the top of the text, or a pixel or two above, and this issue only occurs with one row of pixels:

<style>
a.button-test {
 display: inline-block;
 padding: 20px;
 background: red;
}
.button-test:active {
 position: relative;
 top: 1px;
}
</style>
<a class="button-test" href="#">Clickedy click</a>

Messing around with the CSS, not using inline-block, increasing line-height instead of padding etc. doesn't seem to have an effect here. I've tried many combinations. Most of my testing has been done in Firefox to allow me to bind to the events and record what's going on through firebug but I also encounter this problem in other browsers.

Does anyone have any inspiration they can offer on this other than lose the active jump? I'd really like to keep this effect if I can.

Big thanks,

Dom (no pun intended)


回答1:


It's much easier to reproduce this problem if you change the style to top: 10px




回答2:


Here's my workaround using a custom event with jQuery

var buttonPressed;
// Track buttonPressed only on button mousedown
$(document).on('mousedown', 'button', function (e) {
    // Make sure we store the actual button, not any contained
    // element we might have clicked instead
    buttonPressed = $(e.target).closest('button');
});
// Clear buttonPressed on every mouseup
$(document).on('mouseup', function (e) {
    if (buttonPressed) {
        // Verify it's the same target button
        var target = $(e.target).closest('button');
        if (target.is(buttonPressed)) {
            buttonPressed.trigger('buttonClick');
        }
        buttonPressed = null;
    }
});

$('button').on('buttonClick', function (e) {
    // Do your thing
});

Just make sure you don't handle both the native click and buttonClick events.



来源:https://stackoverflow.com/questions/2111289/when-a-mousedown-and-mouseup-event-dont-equal-a-click

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!