How to get the state of the mouse through JavaScript - javascript

I want to get whether the current mouse is pressed, such as the right button.
I know that you can use mousedown to maintain a variable to determine whether it has been pressed.
But when mouseup on a disabled element, there is no way to set state to up, which leads to subsequent state errors.
Is there an api to help me get the current mouse state?
example
<button disabled>disabled</button>
let state = 'up'
document.addEventListener('mousedown', () => {
state = 'down'
console.log('mouseDown')
})
document.addEventListener('mouseup', () => {
state = 'up'
console.log('mouseup')
})
document.addEventListener('mousemove', () => {
console.log('mousemove',state)
})

according to the the HTML Spec
A form control that is disabled must prevent any click events that are queued on the user interaction task source from being dispatched on the element.
So you can hack the behaviour using Capturing pointer events
give your button an id ex: "mybutton"
button=document.getElementById('mybutton')
button.addEventListener('click',()=>{
console.log('click')
})
button.addEventListener('pointerdown', event => {
console.log('down')
});
button.addEventListener('pointerup', event => {
console.log('up')
});
OR remove the disabled attribute and use css pointer-events: none this will prevent the button from responding and also you will still be able to get the mouse events

Related

In SvelteKit, is there a way to cancel a popstate event if user state isn't saved?

I have a component that allows a user to edit their state. This triggers a notSaved variable. I have a beforeunload event handler to handle reload and exiting the page to remind the user to save their state, but using SvelteKit, using the back button in the browser doesn't seem to trigger the beforeunload event. I also have a popstate event handler, because that is triggered when the back button is clicked, but I can't figure out how to prevent the window.history from changing if the notSaved variable is true.
Is there a way in SvelteKit to trigger a Changes you made may not be saved. popup similar to the one that is triggered on a beforeunload event when the back or forward button is pressed?
You can use the beforeNavigate function to be notified of a navigation intent in order to potentially block it, for example:
<script>
import { beforeNavigate } from '$app/navigation';
let unsavedWork = false;
let value = 0;
beforeNavigate(({ from, to, cancel }) => {
if (unsaved) {
cancel();
showUnsavedWorkPopup();
}
});
function onChange() {
...
unsavedWork = true;
}
async function save() {
await ...
unsavedWork = false;
}
</script>
<input type="number" bind:value on:change={onChange}>

Disabling all clicks and keyboard input until all code is finished running

I have several animations that show and hide elements, and if the user clicks too quickly several animations will play at the same time which creates bizarre glitches.
Right now I'm using a global is_freeze_input variable to prevent certain buttons from being pressed while animations are playing, but I have so many functions which each toggle this variable, so clicking rapidly can sometimes bypass this method of preventing input since the asynchronous nature of JavaScript means I never know when one function is freezing the input or another is unfreezing it.
I thought the cleanest solution would be to disable all input while any animations are playing. Is there a way to do that without manually toggling a variable at the beginning and end of the function?
If I use an event listener to check for all key presses and clicks, can I ignore the input entirely if any part of my code is still processing?
Edit: I have a solution that almost works using the transitionend event listener trigger. This works to disable clicks too soon, but I'm unable to get keypresses to resume after the first time the function is called.
What am I doing wrong?
const handleInput = () => {
document.removeEventListener('keydown', checkKeyDown)
document.removeEventListener('keyup', checkKeyUp)
document.removeEventListener('mouseup', handleInput)
document.removeEventListener('keyup', handleInput)
document.addEventListener('transitionend', () => {
console.log('handleClick transition end')
document.addEventListener('keydown', checkKeyDown)
document.addEventListener('keyup', checkKeyUp)
document.addEventListener('mouseup', handleInput)
document.addEventListener('keyup', handleInput)
}, { once: true })
}
document.addEventListener('keydown', checkKeyDown)
document.addEventListener('keyup', checkKeyUp)
document.addEventListener('mouseup', handleInput)
document.addEventListener('keyup', handleInput)
You can do something like this:
To disable the keyboard inputs:
document.onkeydown = () => false
To enable them back again:
document.onkeydown = () => true
To disable clicks:
document.onclick = () => false
To enable them back again:
document.onclick = () => true
Edit:
To implement this in your project, I would suggest you do something like this:
Create a function to disable all at the same time
function disableAll() {
document.onkeydown = () => false;
document.onclick = () => false;
}
Create a function to enable all at the same time
function enableAll() {
document.onkeydown = () => true;
document.onclick = () => true;
}
And then, as bjb568 suggested, you could use a variable:
that starts at zero, is incremented when an animation starts, and is decremented with one ends.
So that when it is cero, no animations are running. You could check after every animation end, if without that animation, the variable is cero, and if it is, you could call enableAll(), and you could call disableAll() at the start of each animation.
Well, I hope I made myself clear, and I wish you luck with your project, Happy Coding!

Javascript event not registering for right click event (in React)

I'm working on a project in React where I need to differentiate between right and left clicks, as well as left and right mouse-downs. I am having no problems at all with the mouse-down event, but am having a big problem with the click event.
In my onMouseDown handler, I'm checking event.button to see weather the mouse-down occurred with the left or right side of the mouse (event.button === 0 for left mouse-down, and event.button === 2 for right mouse-down). This is working perfectly as expected.
However, the exact same logic is not working for the click event on my onClick handler; only the left click is working. In fact, when I try to log the entire event object on click, there is no response at all with the right click. It's as if the click event doesn't work for right clicks.
For context, I have turned off the context menu on the element I'm talking about because that was getting in the way, but even when I allow the context menu as normal I am having no luck with the right click event.
Here is some code to show you what I'm talking about:
// Works perfectly
const handleMousedown = (e) => {
if (e.button === 0) {
setLeftMousedown(true);
// console.log(e.button);
}
if (e.button === 2) {
setRightMousedown(true);
// console.log(e.button);
}
};
*******************************
// Does NOT work for the right click, and the console.log at the top only fires at all on left clicks
const handleClick = (e, i, j) => {
console.log(e); // only registers for left click
if (e.button === 0) {
let gridCopy = JSON.parse(JSON.stringify(grid));
gridCopy[i][j].on = !gridCopy[i][j].on;
setGrid(gridCopy);
}
if (e.button === 2) {
console.log('rightclick');
let gridCopy = JSON.parse(JSON.stringify(grid));
gridCopy[i][j].wall = !gridCopy[i][j].wall;
setGrid(gridCopy);
}
};
Any ideas why this is happening OR how I can register right click events separate from left click events?
Click events don't work with right mouse button. You should ever use mouseDown or use onContextMenu: https://stackoverflow.com/a/28656242/4949918
For right click, you need to set the onContextMenu prop
onContextMenu={this.handleClick}

How do you "bypass" mouse up?

I am trying to make it so that when a user clicks down, this happens.
In order,
Does something. (Not being specific, this isn't the important part.)
Mouse up is triggered.
Using: angular, html, css.
Not using: jQuery
Any suggestions?
Thanks!
You attach two event listeners, one while the user has the mouse pressed down mousedown. Once the user lets go the mouseup event is triggered. All mouse event listeners are passed an event object you can use to get information about the event ie: mouse x, and y positions.one of the methods available is event.preventDefault() this will stop the browser doing what it usually wants to do. Example: cmd/ctrl + s will cause the browser to save the html page. preventDefault will stop this.
document.addEventListener('mousedown' function (event) {
// Do something
})
document.addEventListener('mouseup', function (event) {
event.preventDefault()
})
To address OP comment:
var noMouseUp = true
document.addEventListener('mousedown', function () {
if (noMouseUp) {
// do something
noMouseUp = false
}
})
document.addEventListener('mouseup', function (event) {
if (!noMouseUp) {
noMouseUp = true
}
})
Use events.preventDefault(); in the mouseup callback.
Use, right after, event.stopPropagation(); to avoid the event passing to other layered elements.
bypassed_element.onclick = function(event){
event.preventDefault();
event.stopPropagation();
};

html element got focused by mouse or keyboard

How can I find out a HTML-Element (lets say a select-tag) got focus by mouse-click, keyboard or JavaScript function?
<select onfocus="foo(event)"></select>
<script>
function foo(e) {
if (e.??? == 'mouse') {
//do something
}
else if (e.??? == 'keyboard') {
//do something different
}
}
</script>
I also tried to add an onclick event to the element but the onfocus event fires first.
I don't believe there is any native way to see how the element received its focus (correct my if I'm wrong!).
However, you may be able to do something like store when the mouse is clicked, store when the keyboard is used and then react based on the last active state.
var inputState = null;
document.addEventListener("click", handleClick);
document.addEventListener("keyup", handleKey);
function handleClick () {
inputState = "mouse";
}
function handleKey () {
inputState = "keyboard";
}
function foo() {
if ( inputState === "mouse" ) {
// mouse code
} else if ( inputState === "keyboard" ) {
// keyboard code
} else {
// Function was called directly
}
// Reset input State after processing
inputState = null
}
This will likely need some adjustments but I hope you can use this to find the correct answer.
Edit:
My answer is a vanilla JS solution, if you have access to jQuery you may want to investigate the click and keyup event handlers.
Use document.activeElement, it is supported in all major browsers. It can give you the current active element.
EDIT
Oops I think I misunderstood your question. you want to identify the mouse or keyboard or programmatic
For programmatic
if(e.hasOwnProperty('originalEvent')) {
// Focus event was manually triggered.
}
To differentiate between keyboard and mouse based focus events
You have to hack it by adding an extra keydown event and understand. You can not differentiate it like you want.
If you want to check wheather < select > is clicked by keyboard or mouse,
you can use mousedown() and keypress() event
$('select').mousedown(function(e){
//your code on mouse select
});
and
$('select').keypress(function(e){
//your code on key select
});

Categories