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)
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.
MouseDown occurs when the user presses the mouse button; MouseUp occurs when the user releases the mouse button.
Mouseup is always firing before click, despite this order.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With