I am working on an application using javascript and I want to get mouse events. To stop the options that appear when right clicking I use the preventDefault() function and it works in Firefox and Chrome but it doesn't work in Safari. This is my code:
document.querySelector("#GL-Surface").addEventListener("mousedown", function(e) {
e.preventDefault();
/* Handle mouse events */
});
From an other question I got that you should return false; but this still doesn't work. preventDefault() however works in Safari when it is used in keyboard inputs. So how can I prevent the default actions for mouse events in Safari?
To target right click events, use contextmenu rather than mousedown.
document.querySelector("#GL-Surface").addEventListener("contextmenu", function(e) {
e.preventDefault();
});
Note that the options that appear on right click do appear only when the right click button is released, so I don't think mousedown is at all suitable here.
Related
So, I have a problem. I want to respond to a user pressing the mouse button (on desktop) or touching a div (on mobile). I'm trying to be compatile with evergreen browsers. This is what I tried so far:
listen only to mouseDown event. This works on desktop but doesn't work in mobile if the user is dragging. I want the handler to be called as soon as the user touches the screen, no matter if they're moving their finger in the process.
listen only to touchStart event. This works on mobile and desktop, except for Edge and Safari desktop, which don't support touch events.
listen to both, then preventDefault. This causes a double handler call on Chrome mobile. It seems that touch events are passive to allow uninterrupted scrolling on mobile Chrome, so preventDefualt has no effect on them . What I get is a warning message saying "[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080" in the console, preventDefault is ignored and my event is called twice.
Obviously this can be solved by sniffing touch events, but the net is full of self-righteous rants on how one has to be device-agnostic and that it's dangerous to detect touch events before the user interacted.
So I guess that the question is: is there a way to do what I want to do without sniffing for touch events?
Below my sample React code:
function handler(e) {
console.log('handler called')
e.preventDefault()
}
export default function MyElement() {
return (
<div
onMouseDown={handler}
onTouchStart={handler}
>
Hello
</div>
)
}
It turn out it's not yet possible in React. One workaround is set a flag the first time touchStart it's received.
touchHandler = () => {
this.useTouch = true
this.realHandler()
}
mouseHandler = () => {
if (this.useTouch) return
this.realHandler()
}
With the caveat that the first touchStart can be lost in case of dragging.
Quite disappointing.
I'm trying to completely remove the vibration that occurs on a long press of an element in a mobile browser.
Specifically, I have an image that I'm adding my own long-press functionality to, but the subtle short-vibrate that happens by default is interfering and I need to disable it.
I've successfully stopped the usual context menu from appearing by overriding it as follows:
window.oncontextmenu = function (event) {
event.preventDefault();
event.stopPropagation();
return false;
};
I've also added CSS to stop highlights and text selection etc - but I haven't been able to figure out what's causing the default vibrate after a few hundred ms.
Is there another lifecycle event that's popped on a long-press in a mobile browser, in or around oncontextmenu?
Full plunker Example here, long-press on the image from a mobile browser (I'm using chrome on Android) to see what I mean: https://plnkr.co/edit/y1KVPltTzEhQeMWGMa1F?p=preview
Disable the text selection when its clicked on.
document.querySelector("#your_target").addEventListener("touchstart", (e) =>
{
e.preventDefault();
e.stopPropagation();
this.style.userSelect = "none";
});
document.querySelector("#your_target").addEventListener("touchend", (e) =>
{
e.preventDefault();
e.stopPropagation();
this.style.userSelect = "default";
});
You could use touch-action: none; in CSS. Then you might be able to handle an interaction event to do what you want.
https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
I'm trying to handle touch/mouse events. So, I created this code:
myObject.addEventListener("touchstart", function(e){
e.stopPropagation();
e.preventDefault();
console.log("Touched");
mouseTouchDown(e);
});
myObject.addEventListener("mousedown", function(e){
console.log("Clicked");
mouseTouchDown(e);
});
function mouseTouchDown(e){
console.log("Some function.");};
I want to stop bubbling of touch event, so click won't be fired afterwards. It works on Chrome, but on Firefox I get in console:
Touched
Clicked
How can I stop mouse click firing after touch event?
I tried returning false, but it doesn't work.
This looks like a bug in the browser, your code looks fine.
See: https://bugzilla.mozilla.org/show_bug.cgi?id=977226.
What OS/version of Firefox are you testing this with?
Have u attached both events with same element?
If that is the case the error is not because of bubbling happening.while mouse click several events will happen like mousedown, touchstart ..etc.so if you want to avoid mouse click event occuring add preventDefault() in the mouse down.This will disable default mouse click event happening on that element.
I'm struggling to disable default taphold browser event. Nothing that I have found on Google provided any help. I have only Android 4.4.4 mobile and Chrome dev tools for testing. I tried CSS fixes, such as webkit-touch-callout and others, but apparently they don't work for Android, also they don't work in Chrome dev tools.
I also tried detecting right click, (e.button==2), it doesn't work.
I came up with a solution, but it solves one problem and creates another. I just want to have a custom action for 'long press' event for selected anchors and I don't want the default pop up to appear (open in a new tab, copy link address, etc.)
This is what I did:
var timer;
var tap;
$("body").on("touchstart", my_selector, function(e) {
e.preventDefault();
timer = setTimeout(function() {
alert('taphold!');
tap=false;
},500);
});
$("body").on("touchend", my_selector, function() {
if(tap) alert('tap');
else tap=true;
clearTimeout(timer);
});
It successfully disables the default taphold event and context menu doesn't appear. However it also disables useful events, such as swipe. The links are in a vertical menu and the menu is higher than the screen, so a user has to scroll it. If he tries to scroll, starting on an anchor, it won't scroll, it will alert 'tap!'
Any ideas how could I disable taphold default or how could I fix this code so it disables only tap events and leave default swipe events enabled?
Edit: Now I thought about setting a timeout, if the pointer is in the same place for lets say 100ms, then prevent default action. However e.preventDefault(); doesn't work inside setTimeout callback.
So now I'm just asking about the simplest example. Can I prevent default actions after certain amount of time has passed (while the touch is still there).
And this is my whole problem in a fiddle. http://jsfiddle.net/56Szw/593/
This is not my code, I got this from http://www.gianlucaguarini.com/blog/detecting-the-tap-event-on-a-mobile-touch-device-using-javascript/
Notice that while swiping the box up and down, scrolling doesn't work.
I got the solution. It was so simple! I had no idea there's an oncontextmenu event. This solves everything:
$("body").on("contextmenu", my_selector, function() { return false; });
For an <img> I had to use event.preventDefault() instead of return false.
document.querySelector('img').addEventListener('contextmenu', (event) => {
event.preventDefault();
}
In Chrome the right-click dialog seems to swallow all mouse events. This means that you get mouse-down events without corresponding mouse-up events.
This includes every right-click, and any left-click where the right button is pressed before the left button is released (in which case you get two mouse-downs but no mouse-ups).
You can see the problem in action here (you may wish to mute your speakers) if you're curious.
I was just wondering if anyone knew of any workarounds for this? Using window.onmousedown instead of document.onmousedown doesn't fix the problem unfortunately.
You'll want to add a handler for the contextmenu event that cancels the opening of that menu.
See MDN for some details.
window.oncontextmenu = function(event) {
event.preventDefault();
event.stopPropagation();
return false;
};