When running on iPhone after double tap and hold on second tap, default iPhone text selection magnifier pops up. I would like to remove it, but had no luck so far.
Here is what it looks in the app ( bubble in the center of the screen )
personally i’d wrap all elements with the following and then only apply the opposite settings to the individual elements that would require it, like so…
from a quick flick through some related issues on github it looks like @PavelBoytchev’s suggestion should do it from inside a touchstart event listener but will also prevent any click event listeners from firing, are you using the dblclick event for this?
I don’t use iOS personally so i won’t be able to test, the iPhone 6 i use for testing i’m sure is still on iOS 14 also…
I need to be using regular touch input. Blocking all input is certainly a solution that would work, but not very practical unfortunately.
I am not using anything myself, it’s happening automaticly. I am not even using any touch events/inputs except for orbit controls.
@Lawrence3DPK The idea with double tap event got me thinking and I did use this function to prevent double tap altogether:
This solves it as the double tap is entirely ignored, so thanks for the suggestion. Not sure, if there is some better solution to catching double tap events. Doubleclick event did not work
window.addEventListener(‘dblclick’, ondblclick, false)
function ondblclick(event)
{ event.preventDefault(); }
ah ok that’s great, to be fair i didn’t even think about the dblclick event not being supported by mobile devices, i just read that it’s not here so if your workaround works it works
So it’s actually still there, it’s just happens less often. Anyways, if you would have some other idea or anyone else, let me know. But thanks for the help.
I think you’ve correctly identified the moment you’d like to intercept the event and precent them. But on recent mobile devices, you’ll need to pass a third parameter into the event listener to say that the event is not passive. Like so:
Update: Mar 28, 2023
Actually, upon further inspecting your gist, you’re not really gaining any advantage from the setTimeout. I’ve re-written it here:
function createHandler(func, timeout) {
let timer = null;
let pressed = false;
return function() {
if (timer) {
clearTimeout(timer);
}
if (pressed) {
if (func) {
func.apply(this, arguments);
}
clear();
} else {
pressed = true;
setTimeout(clear, timeout || 500);
}
};
function clear() {
timeout = null;
pressed = false;
}
}
// ....
// And you would use it like this:
const ignore = createHandler((e) => e.preventDefault(), 500);
document.body.addEventListener('touchstart', ignore, { passive: false });
For Mobile Safari, the actions go like this:
touchstart
touchend Release quickly
touchstart Second one to hold
Magnifying glass comes up
So, if you want to capture the magnifying glass pick up, you need to intercept that second touchstart — not the end or cancel event.
The solution from @jonobr1 works - however I have a solution for those who care more about preventing the following “Share” button that appears after the magnifier rather than the magnifier itself, and for those who don’t want to prevent clicks happening in rapid succession. It simply involves adding dummy text hidden on the page that grabs the attention of the magnifier:
With tailwind:
Dummy Text
Without tailwind:
<span
style={{
position: “absolute”,
bottom: “-100px”,
userSelect: “text”,
WebkitUserSelect: “text”,
opacity: 0,
pointerEvents: “none”,
}}
>
Dummy Text
You may also need aria-hidden=“true”.
For me this prevents all buttons from appearing entirely, the magnifier just disappears - but if a menu pops up for you, it should pop up at the bottom with a “Copy” menu that disappears after another click rather than the persistent “Share” button getting in the way. It will also appear at the bottom of the screen rather than the top left - which on iOS Safari only covers the URL rather than the page. If the URL is placed differently on another browser you can adjust the spans position accordingly.