Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)

like image 672
dmnc Avatar asked Jan 21 '10 17:01

dmnc


People also ask

Do the mouse events click and Mousedown have the same functionality?

Note: This differs from the click event in that click is fired after a full click action occurs; that is, the mouse button is pressed and released while the pointer remains inside the same element. mousedown is fired the moment the button is initially pressed.

What is the difference between mouseup and Mousedown?

MouseDown occurs when the user presses the mouse button; MouseUp occurs when the user releases the mouse button.

Does mouseup fire before click?

Mouseup is always firing before click, despite this order.

How do I trigger a mouseup event?

The mouseup event occurs when the left mouse button is released over the selected element. The mouseup() method triggers the mouseup event, or attaches a function to run when a mouseup event occurs. Tip: This method is often used together with the mousedown() method.


1 Answers

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.

like image 111
James Wheare Avatar answered Oct 20 '22 21:10

James Wheare