I have an application where elements inside of a SVG element can be drag and dropped (thanks to d3-drag and d3-zoom, see https://bl.ocks.org/mbostock/3127661b6f13f9316be745e77fdfb084 as an example for such a page) which can be also used on touch-enabled devices but what happens is that after a long press a context menu pops up (at least in IE11, Edge and Firefox) and is in the way, therefore I want to prevent the context menu from showing up in this case.
I could just disallow showing the context menu in general by handling the contextmenu event and doing .preventDefault() on the event object but I wonder whether a solution exists where the context menu is just blocked from showing in the touch case and it would still show up for e.g. right-clicks or when the menu key is pressed while the element has focus.
I thought at first I could look at the .button and .buttons properties of the event object but it seems like those values are arbitrarily 0 or 2 and it looks like it can be found in any combination when testing in various browsers on different systems.
The element already has touch-action: none.
Is there some working way to make the context menu just not show up a result of a touch long-presses?
It looks like .preventDefault() on the relevant touch events wouldn't be an option.
You can detect if the event is a touch event or not using the touches property of the event object. If the touches property is not empty, it is a touch event, otherwise, it's a mouse event.
You can then use this information to prevent the context menu from showing up only in the touch event case, like so:
element.addEventListener('contextmenu', (event) => { if (event.touches.length) { event.preventDefault(); } });
This way, the context menu will only be prevented from showing up in the touch event case, and it will still show up for right-clicks or when the menu key is pressed while the element has focus.