I am quite new to jquery and looking for event that handles mouse down event. Over now I have found and use something like:
$("#canva").live('mousedown mousemove mouseup', function(e){ ....
but it fires function(e) even when mouse is over canvas element (both when the left button is clicked or not).
I am looking forward to event that will be fired in every change of coordinates above #canva element and when my mouses button is clicked. Releasing left mouse button should cause end of this event.
One way to do this would be to create a global variable and to modify its value when the user clicks over the element as such:
var mouseIsDown = false;
$('#mycanvas').on('mousedown', function () {mouseIsDown = true});
$('#mycanvas').on('mouseup', function () {mouseIsDown = false});
Now all you have to do is to bind 'mousemove' to the function you want to fire and simply appending a conditional to the body of the function that checks the state of the left click and escapes if necessary.
function fireThis(e) {
// if the user doesn't have the mouse down, then do nothing
if (mouseIsDown === false)
return;
// if the user does have the mouse down, do the following
// enter code here
// ....
// ....
}
// bind mousemove to function
$('#mycanvas').on('mousemove', fireThis);
Now, if the user were to click inside the element and then drag the mouse outside the element before releasing, you'll notice that 'mouseup' will never get triggered and the variable mouseIsDown will never be changed back to false. In order to get around that, you can either bind 'mouseout' to a function that resets mouseIsDown or bind 'mouseup' globally as such:
$('#mycanvas').on('mouseout', function () {mouseIsDown = false});
OR
$(document).on('mouseup', function () {mouseIsDown = false});
Here's an example: http://jsfiddle.net/pikappa/HVTWb/
Related
I have a program that simulates a cloth (made by spring and vertices) in WebGL. What the program must do is to permit the user to click on a point in the cloth, dragging it following the mouse and if the user clicks again, release it. I need to check which click event is the one that starts the dragging and which one terminates it, then I used a global variable "clicked", set it to false at the beginning and swapped everytime the event click is triggered. Now for the dragging I need periodically to take the coordinates of the mouse, then I though using a "mousemove" event was the best solution: if the "clicked" is set to true, this means that we are in the "dragging phase", then the mousemove event must be called and continue to work until the next click event. The problem is that I don't know how to use the mousemove in connection to the click event: if I put the mousemove event outside the click event, we never enter in that, and if I put the mousemove event inside the click event, also if the "clicked" variable change from true to false, the mousemove event is always called. The skeleton of the code is the following one:
var clicked = false;
function exec() {
let web_gl = document.getElementById("webgl-canvas").getContext('webgl2');
web_gl.canvas.addEventListener('click', (e) => {
clicked = !clicked;
console.log(clicked);
if (clicked == true) {
web_gl.canvas.addEventListener('mousemove', (e) => {
//do something for dragging
});
};
});
}
function main() {
exec();
};
Here also if the console prints both false and true in the correct way, we enter always in the if condition, it seems the condition sees "clicked" always true.
The other option was this one:
var clicked = false;
function exec() {
let web_gl = document.getElementById("webgl-canvas").getContext('webgl2');
web_gl.canvas.addEventListener('click', (e) => {
clicked = !clicked;
console.log(clicked);
});
if (clicked == true) {
web_gl.canvas.addEventListener('click', (e) => {
\\do something for dragging
});
}
}
function main() {
exec();
};
In this case we never enter in the event, and I don't understand why.
Does someone have an hint about this problem, or a better idea to handle what I need to implement?
Adressing your second snippet: your code is executed asynchronously, the event handlers are not executed until the event is emitted, hence clicked will still be in its initial state (false) when the condition to add the mousemove handler is evaluated, thus is will not be added and hence never be executed.
What you want to do is to add both event handlers and check within the mousemove event handler if clicked is true.
Btw. the logic you're about to implement means that a user has to click(mouse down and up) to activate the dragging and click again to disengage, rather than what's common UI practice: click(mousedown) and hold to drag things.
I found the solution. I used the click event in the main() function that is called only once, set a flag such that it is negated when a click is detected (passing from false to true and vice-versa). Inside the click event, if the flag is true, this is the first click, I add the mousemove event, picking the coordinates.
I'm building a dragging widget thingy, it listens to 'mouseup'/'mousedown' events from the interactive element.
Works fine most of the time but I've found the 'mouseup' to be a bit unreliable. Is there an event independent way of checking whether the mouse buttons are up/down? I could attach it to a timer or the mousemove event to make it foolproof.
You have to use an event however you can have script from within the events to assign the state of the mouse down that you can test later.
var isMouseDown = false;
document.addEventListener("mousedown", function()
{
isMouseDown = true;
});
document.addEventListener("mouseup", function()
{
isMouseDown = false;
});
if (isMouseDown == true) { ... }
Is there an event independent way of checking whether the mouse buttons are up/down?
No, there isn't. But for your dragging code, your best bet for listening for mouseup isn't the element you're dragging, but the document as a whole. You still won't get the event if the mouse release is outside the window, but you will if the mouse has been moved abruptly and released such that it's outside your element when the release occurs.
You can also listen for mousemove, which of course fires a lot, and also tells you whether buttons are down (via the buttons property on the event object).
I am creating a basic text window in easeljs. The text window has up and down scroll arrows to enable the scrolling of the text. I do this simply by listening for a click on the up or down button and then moving the y coordinates of the text box on the click.
The problem I have is that it only moves once per click. If I have a lot of text to scroll, I have to click a lot of times. What I want is to be able to click and hold the button and have the listener repeat the action whilst the mouse is down?
Here's my simplified code attached to the down button:
btn_down.on("mousedown", function(evt) {
content.y -= 20;
game.stage.update();
});
I have tried mousedown and click, but it still only seems to fire once.
The mousedown event fires once (when you press your mouse button). If you want to loop an event while the mouse is down, either set an interval when the mouse is pressed (and clear it when it is released), or toggle a property that causes an update during a tick.
http://jsfiddle.net/lannymcnie/t7uz2v6m/
shape.on("mousedown", handlePress);
shape.on("pressup", handleRelease);
var pressed = false;
function handlePress(event) { pressed = true; }
function handleRelease(event) { pressed = false; }
function tick(event) {
if (pressed) { shape2.x += 1; }
stage.update(event);
}
Note that I use the "pressup" event instead of the mouseup equivalent (click), because if you roll out and release, the "pressup" event still fires.
Cheers.
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?
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.
window.addEventListener('mouseup', function(event){
// do logic here
})
It handle releasing mouse even outside of browser
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!
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/
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);
})
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;
}
});
I've downloaded a JQuery plugin for a mousehold event.
http://remysharp.com/2006/12/15/jquery-mousehold-event/
I have this div that calls for mousemove event:
div.addEventListener('mousemove',function() {
//things
});
whenever I call the mousehold event like this:
var value = 0;
$(div).mousehold(function() {
value += 20;
$(div).html(value);
});
it would work. But if I start moving (thus, calling the mousemove event) while onmousehold, the value does not increase anymore, meaning, it stopped calling the mousehold event even if I got my left click still on hold.
How can I make it happen that when I do a mousemove, the mousehold event still works? tnx!
What you're asking (at least, what I think you're asking), is simple enough with some basic logic.
By binding the mousedown, mousemove, and mouseup and setting a flag for the "down" state of the mouse, this can easily be done: JSFiddle
You could use the event object like so:
div.addEventListener('mousemove', function(event) {
// `event.buttons` gets the state of the mouse buttons
// 0 = not pressed, 1 = left click pressed, 2 = right click pressed
if (event.buttons === 1) {
value += 20;
}
});