Ωmega
Ωmega

Reputation: 43663

How to catch mouse-up event outside of element?

I have simple Javascript code, similar to this one:

var mouseIsDown = false;
...
function canvasMouseDown(e) {
  ...
  mouseIsDown = true;
}
function canvasMouseUp(e) {
  mouseIsDown = false;
}
function canvasMouseMove(e) {
  if (mouseIsDown) {
    ...
  }
}

with implemention my own user interface for tranformations (translations, scalings and rotations) with canvas.

Such implementation within canvasMouseMove() function check mouseIsDown variable. All works fine if user does not release mouse button when the cursor/pointer is outside of the canvas element. If that happen, the variable mouseIsDown stays true and is not turned off by canvasMouseUp function.

What is easy fix or solution in pure JavaScript (no jQuery) for this issue?

Upvotes: 56

Views: 59228

Answers (7)

Vladimir Panteleev
Vladimir Panteleev

Reputation: 25187

The modern correct answer seems to be to use setPointerCapture:

https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture

This will let you receive e.g. mouse coordinates while the mouse is outside the browser window (and the mouseup event, of course).

Upvotes: 2

Robin Wieruch
Robin Wieruch

Reputation: 15898

In JavaScript, it would be the following:

myElement.addEventListener('mousedown', () => {
  const handleMouseUp = (event) => {
    // check whether outside the element with event.target and myElement

    document.removeEventListener('mouseup', handleMouseUp);
  };

  document.addEventListener('mouseup', handleMouseUp);
})

Upvotes: 7

Bergi
Bergi

Reputation: 664185

If you want to catch the mouseup event somewhere else in the document, you might add an event handler for this to the documentelement. Note that this won't react on mouseup events outside the viewport, so you might want to fire also when the mouse enters the viewport again without a pressed button.

If you want to catch the mouse leaving your canvas element, it gets a bit more complicated. While IE knows a mouseleave event, the standard DOM has a mouseout event that also fires when a descendant of your element is left (although canvas usually has no child elements). Read more on that at quirksmode.org.

I have created a fiddle to demonstrate the behaviour (works only with W3 DOM). You might try to change documentelement to body. In Opera, the mouseup listener on <html> event detects mouseup events outside the document when the "drag" began inside it - I do not know whether that is standard behaviour.

Upvotes: 32

mepler
mepler

Reputation: 947

I created a variable that stored the id string of the target element upon mousedown. On a mouseup event, I check the string to see if it is null. If it isn't, I use the string to get the element and do whatever I want in the code block and then reset the variable to null.

IN other words, steps are:

1.) make a variable, set it to null. 2.) on "mousedown", save the id or class string to the variable. 3.) on "mouseup", check the variable (for safety). If it's not null. then use the string to grab the element and use it to do something. 4.) Then reset the variable to null.

var thisTarget = null

// when I know they click in the right place, save the target. 
// you may not need parent(). I was using a UI slider and needed it.

$(".section").mousedown( function(e) {
    thisTarget = $(e.target.parent().attr('id');
    console.log(thisTarget);
});

// anywhere on the page... 
$(document).mouseup( function(e) { 
    // because I'll make it null after every mouseup event.
    if (thisTarget !== null) { 
        console.log( $("#" + thisTarget) ); // returns element
        // do something with it
        thisTarget = null;
    }
});

Upvotes: 2

Developia
Developia

Reputation: 4008

window.addEventListener('mouseup', function(event){
// do logic here
})

It handle releasing mouse even outside of browser

Upvotes: 30

matdumsa
matdumsa

Reputation: 16105

document.onmouseup will be thrown even outside the viewport, that's a nice-to-know you only get by binding to the document object. test here: http://jsfiddle.net/G5Xr2/

$(document).mouseup(function(e){
  alert("UP" + e.pageX);
});

It will even receive the mouse position!

Upvotes: 10

Waleed Khan
Waleed Khan

Reputation: 11467

Add a higher-level event handler (perhaps to the body) that catches the mouseUp event, and sets mouseIsDown to false.

Here's a demo: http://jsfiddle.net/ZFefV/

Upvotes: 6

Related Questions