Need to Cancel Click/Mouseup Events When Double-Click Event Detected

Need to cancel click/mouseup events when double-click event detected

This is a good question, and I actually don't think it can be done easily. (Some discussion on this)

If it is super duper important for you to have this functionality, you could hack it like so:

function singleClick(e) {
// do something, "this" will be the DOM element
}

function doubleClick(e) {
// do something, "this" will be the DOM element
}

$(selector).click(function(e) {
var that = this;
setTimeout(function() {
var dblclick = parseInt($(that).data('double'), 10);
if (dblclick > 0) {
$(that).data('double', dblclick-1);
} else {
singleClick.call(that, e);
}
}, 300);
}).dblclick(function(e) {
$(this).data('double', 2);
doubleClick.call(this, e);
});

And here is an example of it at work.

As pointed out in the comments, there is a plugin for this that does what I did above pretty much, but packages it up for you so you don't have to see the ugly: FixClick.

Cancel click event in the mouseup event handler

I had the same problem and didn't found a solution either. But I came up with a hack that seems to work.

Since the onMouseUp handler doesn't seem to be able to cancel the click on a link with preventDefault or stopEvent or anything, we need to make the link cancel itself. This can be done by writing an onclick attribute which returns false to the a-tag when the drag begins, and removing it when the drag ends.

And since the onDragEnd or onMouseUp handlers are run before the click is interpreted by the browser, we need to do some checking where the drag ends and which link is clicked and so on. If it ends outside the dragged link (we dragged the link so that the cursor isn't on the link anymore), we remove the onclick handler in the onDragEnd; but if it ends where the cursor is on the dragged link (a click would be initiated), we let the onclick-handler remove itself. Complicated enough, right?

NOT COMPLETE CODE, but just to show you the idea:

// event handler that runs when the drag is initiated
function onDragStart (args) {
// get the dragged element
// do some checking if it's a link etc
// store it in global var or smth

// write the onclick handler to link element
linkElement.writeAttribute('onclick', 'removeClickHandler(this); return false;');
}

// run from the onclick handler in the a-tag when the onMouseUp occurs on the link
function removeClickHandler (element) {
// remove click handler from self
element.writeAttribute('onclick', null);
}

// event handler that runs when the drag ends
function onDragEnds (args) {
// get the target element

// check that it's not the a-tag which we're dragging,
// since we want the onclick handler to take care of that case
if (targetElement !== linkElement) {
// remove the onclick handler
linkElement.writeAttribute('onclick', null);
}
}

I hope this gives you an idea of how this can be accomplished. As I said, this is not a complete solution, just explaining the concept.

MouseUp and DoubleClick both attached to seperate event handling functions using Backbone js

Following the advice given in the answer you linked, you just have to debounce the callback for a mouseup and check if a second click occurs in a given period.

Assuming a view defined in this manner (http://jsfiddle.net/nikoshr/4KSZx/)

var V = Backbone.View.extend({
events: {
'mouseup button': 'onmouseup',
'dblclick button': 'ondblclick'
},

onmouseup: function() {
console.log('mouseup');
},
ondblclick: function() {
console.log('dblclick');
}
});

you could modify it and "cancel" the mouseup event:

var V = Backbone.View.extend({
events: {
'mouseup button': _.debounce(function(e) {
if (this.doucleckicked) {
this.doucleckicked = false;
} else {
this.onmouseup.call(this, e);
}
}, 300),
'dblclick button': function(e) {
this.doucleckicked = true;
this.ondblclick.call(this, e);
}
},

onmouseup: function() {
console.log('mouseup');
},
ondblclick: function() {
console.log('dblclick');
}
});

And a demo http://jsfiddle.net/4KSZx/6/

How to prevent MouseUp event after DoubleClick on Window TitleBar in WPF?

This should work just fine:

Solution:

  //WNDPROC INTEROP
private const int WM_NCLBUTTONDBLCLK = 0x00A3;

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
//TITLE BAR DOUBLE CLICK
if (msg == WM_NCLBUTTONDBLCLK)
{
Console.WriteLine("titlebar double click " + this.WindowState);

//WINDOW ABOUT TO GET MAXIMIZED
if (msg == WM_NCLBUTTONDBLCLK)
handleNextMouseup = true;

else if (msg == 0x202) // mouseup
{
if (handleNextMouseup)
handled = true;

handleNextMouseup = false;
}
}

return IntPtr.Zero;
}

another possible solution:

  //WNDPROC INTEROP
private const int WM_NCLBUTTONDBLCLK = 0x00A3;

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
//TITLE BAR DOUBLE CLICK
if (msg == WM_NCLBUTTONDBLCLK)
{
Console.WriteLine("titlebar double click " + this.WindowState);

//WINDOW ABOUT TO GET MAXIMIZED
if (this.WindowState == WindowState.Normal)
{
fakehittestvisible = true;

}
}

return IntPtr.Zero;
}

private bool fakehittestvisible = false;

//ON PREVIEW MOUSE UP ABORT IF MIXIMIZING HAPPENED
private void this_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
if (fakehittestvisible)
{
e.Handled = true;
fakehittestvisible = false;
return;
}

fakehittestvisible = false;
Console.WriteLine("this mouse up state is " + this.WindowState);
}

Prevent click event from firing when dblclick event fires

In a comment, you said,

I delay the click handler by 300 ms (a noticeable and annoying delay) and even ...

So it sounds like what you want is that when you click then the DOM should geneate a click event immediately, except not if the click is the first click of a double-click.

To implement this feature, when you click, the DOM would need to be able to predict whether this is the final click or whether it's the first of a double-click (however I don't think is possible in general for the DOM to predict whether the user is about to click again).


What are the two distinct actions which you're trying to take on click and double-click? IMO, in a normal application you might want both events: e.g. single-click to focus on an element and then double-click to activate it.

When you must separate the events, some applications use something other than double-click: for example, they use right-click, or control-click.

Backbone.js - Both click and double click event getting fired on an element

This isn't an issue with Backbone itself.
It's about how to handle both single click and double click events on the same button.

See

  1. Need to cancel click/mouseup events when double-click event detected

  2. Javascript with jQuery: Click and double click on same element, different effect, one disables the other

Update: But it would be better if you didn't have to deal with it. See mu is too short's answer below!

Javascript how to distinguish between mouseDown, click and doubleClick events

dblclick event fires after two click events and after two pairs of mousedown and mouseup events.

Usually, we see such a case when for example selecting/focusing a file by a single click and then executing a file by double click. There is no harm in selecting the same file multiple times.

If you need to distinguish these two events, you can postpone single click handling until you are sure it is not part of the double click, but this will add a delay in handling.

let clicks = 0;
let clickTimer = 0;
const dblClickTimeSpan = 300;

const clickHandler = (e) => {
clicks++;
if(clicks === 1) {
clickTimer = setTimeout(()=>{
clicks = 0;
// handle single click, now we are sure it is not a bouble click
console.log('Single Click.')
}, dblClickTimeSpan);
}
if(clicks === 2) {
// it is the second click in double-click event
clearTimeout(clickTimer);
clicks = 0;
}
}

myButton.addEventListener('click', clickHandler);
myButton.addEventListener('dblclick', (e) => console.log('Double Click.'));
<button id="myButton">Button</button>


Related Topics



Leave a reply



Submit