Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel click event in the mouseup event handler

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; }); 
like image 285
Yaron Avatar asked Dec 27 '11 10:12

Yaron


People also ask

How do I stop a click event?

To stop the click event from propagating to the <div> element, you have to call the stopPropagation() method in the event handler of the button: btn. addEventListener('click', (e) => { e. stopPropagation(); alert('The button was clicked!

How do you delete a click event in an element?

The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.

Does mouseup fire before click?

Mouseup is always firing before click, despite this order.

Is Mousedown the same as click?

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.


2 Answers

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.

var btnElm = document.querySelector('button');    btnElm.addEventListener('mouseup', function(e){      console.log('mouseup');            window.addEventListener(          'click',          captureClick,          true // <-- This registeres this listener for the capture               //     phase instead of the bubbling phase!      );   });    btnElm.addEventListener('click', function(e){      console.log('click');  });    function captureClick(e) {      e.stopPropagation(); // Stop the click from being propagated.      console.log('click captured');      window.removeEventListener('click', captureClick, true); // cleanup  }
<button>Test capture click event</button>

JSFiddle Demo

What happens:

Before the click event on the button is triggered the click event on the surrounding div gets fired because it registered itself for the capture phase instead of the bubbling phase.

The captureClick handler then stops the propagation of it's click event and prevents the click 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.

like image 104
flu Avatar answered Oct 14 '22 01:10

flu


There is a solution!

This approach works for me very well (at least in chrome):

on mousedown I add a class to the element that is currently being moved and on mouseup I remove the class.

All that class does is sets pointer-events:none

Somehow this makes it work and click event is not fired.

like image 23
FDIM Avatar answered Oct 14 '22 02:10

FDIM