Reputation: 43663
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
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
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
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
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
Reputation: 4008
window.addEventListener('mouseup', function(event){
// do logic here
})
It handle releasing mouse even outside of browser
Upvotes: 30
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
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