Writing some drag&drop code, I'd like to cancel the click events in my mouseup handler. I figured preventing default should do the trick, but the click event is still fired.
Is there a way to do this?
This doesn't work:
<div id="test">test</div>
<script>
$("#test").mouseup (function (e) {
var a = 1;
e.preventDefault();
});
$("#test").click (function (e) {
var a = 2;
});
The best solution for my situation was:
This gives the user 150ms to release, if they take longer than 150ms it's considered a pause, rather than a click
The important thing to note is the
event
parameter.EDIT: You want to cancel the drag?
The way I know to do this is to either use
bind()
(for older jQuery versions) oron()
(for jQuery 1.7+) to attach the mousedown event, then useunbind()
oroff()
respectively to detach it.As they are different events, you cannot cancel
onclick
fromonmouseup
, if you callpreventDefault
orcancelBubble
, or whatever, you are stopping theonmouseup
event from being processed any further. Theonclick
event is still pending, yet to be fired, so to speak.What you need is your own boolean flag, e.g.
isDragging
. You can set this to true when dragging starts (e.g. withinonmousedown
, or whatever).But if you reset this to false directly from
onmouseup
, you will not be dragging any more when you receive youronclick
event (isDragging == false
), becauseonmouseup
fires beforeonclick
does.So what you need to do is use a short timeout (e.g.
setTimeout(function() {isDragging = false;}, 50);
), so when youronclick
event is fired,isDragging
will still betrue
, and youronclick
event handler can simply haveif(isDragging) return false;
before it does anything else.the solution that i use is the following:
attach each function to the appropriate event according to the name !
My solution doesn't require global variables or timeouts or changing html elements just jquery which surely has some aquivalent in plain js.
I declare a function for onClick
I declare a function for MouseDown (u may also do the same in mouse up) to decide if to handle an onclick event or not
Quick Note: you should make sure that
$('#domElement').on("click", onMouseClick);
is not executed multiple times. Seems to me that in case it is the onMouseClick will be called multiple times too.Use the event capture phase
Put an element around the element you want to cancel the click event for, and add a capture event handler to it.
JSFiddle Demo
What happens:
Before the click event on the
button
is triggered the click event on the surroundingdiv
gets fired because it registered itself for the capture phase instead of the bubbling phase.The
captureClick
handler then stops the propagation of it'sclick
event and prevents theclick
handler on the button to be called. Exactly what you wanted. It then removes itself for cleanup.Capturing vs. Bubbling:
The capture phase is called from the DOM root up to the leafs while the bubbling phase is from the leafs up the root (see: wonderful explanation of event order).
jQuery always adds events to the bubbling phase that's why we need to use pure JS here to add our capture event specifically to the capture phase.
Keep in mind, that IE introduced the W3C's event capturing model with IE9 so this won't work with IE < 9.
With the current Event API you can't add a new event handler to a DOM Element before another one that was already added. There's no priority parameter and there's no safe cross-browser solution to modify the list of event listeners.