I have a button when pressed or on mouse-down event on it sends a command. It should also send a command when the button is released(as we don't have any release event, to my knowledge), I am using mouse-up event on the button. When i use the long press on the button from computer browser the mouse-up event works, But when i use mobile browser, if i do a long press on it the mouse up event is not fired, as the mobile browser will have text selection feature on long press. Could some one help me with this.
When the user interacts with your application using a mouse, it will respond via 'click' event, but when the user uses touch enable devices and touches the screen both 'touch' and 'click' event will occur.
for the single touch following events will occur in order :
touchstart
touchmove
touchend
mouseover
mousemove
mousedown
mouseup
click
one other 'touchcancel' will occur if the touch is interrupted.
When the user touches the screen, mouse events also executes. To avoid this, stop the default actions of touch events using preventDefault() method of event handler object,(e.preventDefault(); where 'e' is the event handler object).
Example :
let timeIn, timeOut;
const touchStart=(e)=>{
e.preventDefault();
console.log('touch start');
timeIn = Date.now();
}
const touchMove=(e)=>{
e.preventDefault();
timeOut= Date.now();
console.log('touch move');
}
const touchEnd=(e)=>{
e.preventDefault();
timeOut=((Date.now()-timeIn)/1000).toFixed(2);
console.log('touch end' , timeOut);
}
const mouseOver=()=>{
console.log('mouse over');
}
const mouseMove=()=>{
console.log('mouse move');
}
const mouseUp=()=>{
console.log('mouse up');
}
const mouseDown=()=>{
console.log('mouse down');
}
const mouseClick=()=>{
console.log('mouse click');
}
const touchCancel=(e)=>{
console.log('touch interrupted')
}
<div
ontouchstart="touchStart(event)"
ontouchmove="touchMove(event)"
ontouchend="touchEnd(event)"
onmouseover="mouseOver(event)"
onmousemove="mouseMove(event)"
onmouseup="mouseUp(event)"
onmousedown="mouseDown(event)"
onclick="mouseClick(event)"
ontouchcancel="touchCancel(event)"
>
touch me
</div>
To test this code on codepane : https://codepen.io/omiGit/pen/MVapRO
There is a good article on touch and mouse, must read: https://www.html5rocks.com/en/mobile/touchandmouse
Related
I have JavaScript code where:
When the user presses the left mouse button, a mousedown event is fired, which triggers a call to function OnMouseDown.
When the user releases the left mouse button, a mouseup event is fired, which triggers a call to function OnMouseUp.
The two events are fired asynchronously.
For example, the mouseup event can be fired immediately after the mousedown event is fired (short mouse click), before the OnMouseDown ends. (Figure1)
I want to process the events sequentially, where the function OnMouseUp will only start after OnMouseDown ends.
I can achieve this by preventing the mouseup event from firing until after OnMouseDown ends (by calling removeEventListener('mouseup', OnMouseUp) when OnMouseDown begins) (Figure2)
But then I may lose a mouseup event altogether (Figure3)
Figure3 - mouseup event is lost
I am looking for a way to insure that
a mouseup event after a mousedown event is not lost, and
the OnMouseUp function begins after OnMouseDown ends.
How can I achieve this?
The following code example demonstrates the problem:
function sleep1 () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Finished sleeping");
}, 2000);
});
}
// The mousedown event is fired when a pointing device button (usually a mouse button) is pressed on an element.
document.addEventListener('mousedown', async function(e) {
console.log('BEG OnMouseDown');
let retval = await sleep1();
console.log('retval: ', retval);
console.log('END OnMouseDown');
});
// The mouseup event is fired when a pointing device button (usually a mouse button) is released over an element.
document.addEventListener('mouseup', function(e) {
console.log('BEG OnMouseUp');
console.log('END OnMouseUp');
});
Clicking on the left mouse button and releasing results in the following printout, which shows that the function OnMouseUp ends before the function OnMouseDown ends, which fits figure1.
BEG OnMouseDown
BEG OnMouseUp
END OnMouseUp
Inside OnMouseDown: Finished sleeping
END OnMouseDown
You can try async await,
Define an async function then use await keyword on the mouswdown event, it will not fire the next event untill the the async function is done
What i'm understanding is that you want to record events in the sequence they have fired.
Please check this solution:
// The mousedown event is fired when a pointing device button (usually a mouse button) is pressed on an element.
var ismousedown = false;
document.addEventListener('mousedown', function(e) {
e.preventDefault();
ismousedown = true;
console.log('BEG OnMouseDown');
});
// The mouseup event is fired when a pointing device button (usually a mouse button) is released over an element.
document.addEventListener('mouseup', function(e) {
e.preventDefault();
if(ismousedown){
ismousedown = false;
console.log('BEG OnMouseUp');
}
});
Is this what you're looking for? There is something else i have missed?
I solved the problem by:
implementing a sleep based on here
introducing a flag onMouseDownStillProcessing that is set to false/true at the beginning/end of OnMouseDown, respectively.
waiting in the beginnning of OnMouseUp for onMouseDownStillProcessing to become true.
I am working on a video player. This player is used inside an iframe on the client's page, so it is cross-origin. When the user clicks on seekbar and drags the cursor out of iframe, I can't identify the mouseup event, so it keeps selected. I notice that youtube player can do it, and can identify cursor events outside iframe. How can i do it using javascript?
One thing to consider is that the mouseup event only fires if the pointer is directly over the element with the eventListener. It doesn't keep track of what element the mousedown event fired on, it only knows about the state of the mouse at the time of the mouseup.
The mouseup event is fired at an Element when a button on a pointing
device (such as a mouse or trackpad) is released while the pointer is
located inside it.
https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseup_event
Therefore you need some other method of tracking if your user has initiated the drag on your seekbar playhead.
A possible solution is to use a boolean variable. Then to listen to mouseup on document and check the value of that variable.
let scrubbingTimeline = false;
document.querySelector('button').addEventListener('mousedown', ()=> {
console.log('Mouse down')
scrubbingTimeline = true
})
document.addEventListener('mouseup', ()=> {
if(scrubbingTimeline === true) {
console.log('Mouse has been released')
scrubbingTimeline = false
}
})
Another possible solution would be to initiate the mouseup listener only once the mousedown callback has fired. Then to stop listening after one event. Like this:
function mouseUpHandler() {
console.log("Mouse Lifted")
document.removeEventListener('mouseup', mouseUpHandler)
}
document.querySelector('button').addEventListener('mousedown', ()=> {
console.log('Down')
document.addEventListener('mouseup', mouseUpHandler)
})
Important: This code is for the inner document. I.E. the one that will be the iframe.
I am trying to create a javascript game, where the user controls the player with keyboard and mouse, the problem is when the keyboard is being used, the mouse event listeners do not work.
document.addEventListener('keydown', _this.addMovements);
document.addEventListener('keyup', _this.removeMovements);
document.addEventListener('mousemove', _this.updateFaceSideEvent);
document.addEventListener('click', _this.fireBulletEvent);
while the keydown event is working, that time the click event or the mousemove event is not working.
Just curious about the purpose of mousedown and mouseup events since they are triggered also on touch devices.
I thought that mousedown and touchstart are mutually exclusive (the former working on desktop while the latter on touch devices) and the same for mouseup and touchend, but it seems this is not the case. A complete touch event triggers all the above events: tested on safari and chrome. Thus to differentiate between a click (mouse) event and a click (touch) event I need to use some kind of function that tells me if this is a touch device or not:
function isTouchDevice() {
return 'ontouchstart' in window // works on most browsers
|| navigator.maxTouchPoints; // works on IE10/11 and Surface
}
myElem.addEventListener("mousedown", () => {
if (isTouchDevice()) return;
// do something
}, false);
myElem.addEventListener("mouseup", () => {
if (isTouchDevice()) return;
// do something
}, false);
myElem.addEventListener("touchstart", () => {
// do something
}, false);
myElem.addEventListener("touchend", () => {
// do something
}, false);
Do I really need to check if a device is touch or not to discriminate between mouse clicks and touch clicks?
No, you don't and probably shouldn't attempt to test if the device is a touch screen or not. If you wish to stop the other events from triggering, you can use the preventDefault method.
myElem.addEventListener("touchstart", (event) => {
event.preventDefault();
// do something
}, false);
If you want more in-depth information, you should read this article: Touch and Mouse
Is touchstart the pendant to click?
If yes, what is it for mousedown? If not what is it then for click?
mousedown = touchstart
click = ?
mouseup = touchend
or
mousedown = ?
click = touchstart
mouseup = touchend
Are mousedown and similar events consistently triggered on mobile devices?
Actually the click is mousedown -> keep focus on element -> mouseup (click is dispatched together with mouseup.
The same applies to touchstart and touchend, click is dispatched with touchend.
Look at following example to get thing clearer:
<html>
<head>
</head>
<body>
<button id="test">test</button>
<script>
document.getElementById("test").addEventListener("mousedown", () => {
console.log("down");
});
document.getElementById("test").addEventListener("click", () => {
console.log("click");
});
document.getElementById("test").addEventListener("mouseup", () => {
console.log("up");
});
</script>
</body>
</html>
You click and hold on test button, you'll see in your console down. Now you release your mouse and you'll see both click and up.
If you click and hold, then you move your pointer away before releasing, you won't see neither click nor up.
Be aware that long time between touchstart and touchend dispatch a contextmenu (right click) instead of just click.