I have a web application in which I have hooked mouse up and mouse down events; I use them for selection and manipulation of the graphical language for which my application is an editor. To prevent the right-click/context menu supplied by Firefox from showing up, I've placed:
if (evt.preventDefault) {
evt.preventDefault();
}
at the top of each of my mouse up and mouse down event handlers. I don't want to return false; I actually want the event to propagate.
On the Mac, the right-click menu doesn't show up; this is what I expect. On Windows, however, it stubbornly appears, even though Firebug confirms that my call to "preventDefault" is occurring and likewise "defaultPrevented" gets set to true.
Any idea what gives? Has anyone else run across this problem? I'm running Firefox 6.0.2 on both the Mac and Windows.
[Update: more recent versions of Firefox yielded consistent results on Mac and Windows: the context menu failed to be suppressed on both platforms.]
Okay. After putting this aside and returning to it several times, I finally found the solution.
Attempting to deal with the appearance of the context menu in the various mouse listeners appears to be fundamentally flawed. Instead, thanks to code I found here, I was put on the scent of the contextmenu event. That event appears to be the right way to handle things, although the code actually posted on that site didn't do the trick — merely calling "stopPropagation" and returning false was insufficient.
The following worked for me:
element.addEventListener('contextmenu', function(evt) {
evt.preventDefault();
}, false);
This has been tested with Firefox 10.0 on a Mac and Firefox 9.0.1 and 10.0 on Windows 7.
This option is removed in Mozilla's 23rd version.
Go to Tools > Options.
Go to the Content tab.
Click Advanced button next to Enable JavaScript option.
Disable or replace context menus. Check this box and it will magically work again.
There is no way to get around this setting in JavaScript.
Related
I've been going somewhat crazy trying to debug a file drag and drop issue in an application I'm working on. What's happening is that Chrome is firing onDragEnter, OnDragOver and onDrop events (the only events I'm using) outside the element on which they're defined but only when devtools is open. I can't share my code but I can reproduce the issue easily using this bare bones example on JSBin: https://jsbin.com/hiqasek/edit?html,js,output
With devtools open, if I drag a file from Finder up toward the target div the onDragEnter event happens when the cursor is about 75 or 100 pixels below the div. If I go ahead and drop the file there the onDrop event fires. The end result is as expected but from the wrong cursor position. Now if I close devtools and do this again, the events fire "pixel perfect" inside the div.
Running in incognito mode with extensions disabled yields the same result.
My setup: MacOS 10.15.7 with Chrome 95.0.4638.69. This did not happen when testing with Edge 95.0.1020.40 and Safari 15 v15612.1.29.41.4.
EDIT: Does not happen in the same version of Chrome on Windows 10 20H2 (19042.1288)
Am I overlooking something (very possible), or is this is a bug in Chrome?
I'm using Google Maps API in my react app. I've added a custom context menu on the maps on the right click button handler. It works absolutely fine on all browsers on Mac. Works fine on IE and Edge on Windows except for Google Chrome and Mozilla Firefox (on Windows OS) where apart from displaying the custom menu, the actual browser context menu also appears.
Here's a jsfiddle which contains a sample code which behaves similarly to how my code works.
Please check the above fiddle on Windows in different browsers and on right clicking the maps, you will see that on Chrome and Firefox, two menu appears and on Edge only the custom one (which is the expected behavior and this also works fine on Mac).
var ContextMenu = document.getElementById("my-context-menu");
google.maps.event.addListener(map, 'rightclick', function (ev) {
ShowContextMenuGoolge(ContextMenu, ev);
/** this stop NOT stopping DOM 'context-menu' event from firing */
ev.stop();
});
google.maps.event.addListener(map, 'click', function () {
HideContextMenuGoolge(ContextMenu);
});
}
Expected behavior (Screenshot from Chrome in Mac):
What actually is happening (Screenshot from Chrome in Windows):
I have tested this solution on both FireFox and Google Chrome so just add this piece of code at the very top of your js file:
window.onload = (function(){
document.addEventListener("mouseup", function(evt){
console.log(evt)
evt.preventDefault();
evt.stopPropagation();
});
document.addEventListener("contextmenu", function(evt){
console.log(evt);
evt.preventDefault();
evt.stopPropagation();
});
})();
Also remove the ev.stop() method as it won't do anything. See below.
JavaScript within the browser is event driven, meaning that JavaScript
responds to interactions by generating events, and expects a program
to listen to interesting events. User events (such as "click" mouse events) are propagated from the DOM to the Maps JavaScript API. These events are separate and distinct from standard DOM events.
See this link for the above reference
Also note that disabling the right-click event via contextmenu in the browser may not be the ideal solution. I suggest additional resarch on your side.
I just spent half a day trying to solve this exact same problem, and the solution posted here and in several other threads on this issue just wouldn't work for me. Here's what did:
// Add a listener to the Intelligence Bounds to serve a context menu
google.maps.event.addListener(myPolygon, 'rightclick', (evt) => {
if (evt.vertex && myPolygon.getPath().getLength() > 4) { // Don't let them delete a node if it would turn us into a line
// Set timeout is used only because it solves the issue of Windows Chrome/Firefox browser context menu overlaying our own
setTimeout(this.onVertexRightclick, 0, evt.vertex, this)
}
});
I honestly don't understand why this works but I'm glad someone posted it. Wrapping the handling of the event in a setTimeout() set to zero ms was the only fix that worked.
All the other fixes I've seen relate to the 3.0 maps API and were posted ~ 2018. I'm using the newer Angular widget that came out in 2019 and is supposed to simplify usage and just wrap the API to my understanding, so perhaps that's the difference in this case.
I have some problem with catching right click event on my web app, tried to use window.oncontextmenu, but for some reasons unknown to me it is not work on Tizen. But when I debug my app via desctop browser, everything work as it should.
What I need to do to activate right click event handler on Samsung TV Tizen?
in general I have lowered my expectations in regards to what will work with the browser running on Tizen displays.
Anyway, a few things that may help you:
Firstly there are oftentimes issues with privileges on Tizen, it's possible that is a problem for you. You can check the privileges available to you for any related to mouse input.
Also I was able to find:
<feature name="http://www.samsungdforum.com/feature/Mouse"/>
Sadly it seems no one really knows what this is or what it does, as the documentation is very poor.
Since you are testing using your device I suspect you have also tested left click. Presumably if that is working it is likely not a privilege issue. In this case I suggest trying a different approach, as I remember to have encountered trouble with events on SAMSUNG browsers as well in the past:
http://developer.samsung.com/tv/develop/guides/user-interaction/mouse
There is some info on setting up the onEvent callback properly.
Last but not least, instead of
window.oncontextmenu
try
document.oncontextmenu
I'm trying to debug a web page that makes heavy use of events, and so I need to monitor all events that are fired.
Most of the events are bound using jQuery. Hence, it would be particularly useful if there was a way to specifically monitor only those events.
Of course you can do just fine with Firebug, the console and the scripts tab where you can add breakpoints and watches, but you want to do it smarter / easier obviously.
There is a neat Firebug plugin called EventBug that just logs all the events and groups them by event type so you can expand and see what triggered them.
EventBug doesn't do it realtime, you have to refresh though.
One other way is to use the 'Log Events' feature against any DOM element in Firebug. This does do it realtime and you can see what order events are fired / triggered as well.
Try this:
Toggle open Firebug
Right click the element in HTML tab, if you want to see all events then right click <body>
Choose Log Events from the context menu
Make sure the Console tab is enabled
Click to enable the 'Persist' mode in the Console tab (otherwise Console tab will clear after the page is reloaded)
You may have to select Closed (manually)
Voila! watch events stream in the console tab
This is what you see with Log Events:
Also worth trying the FireQuery add-on for Firebug to see what elements in the DOM have jQuery events attached to them and what they are.
And as benvie's answer mentions, this is possible in webkit's developer tools as well.
This has been introduced some versions ago but as of Firefox 35 events associated with an element can be seen on the Inspector: next to the element which you want to see the events (in case there is any) there will be an icon with the 'EV' letters. Click it and you will see a small popup window with the events for that element.
More info: http://flailingmonkey.com/view-dom-events-in-firefox-developer-tools/
This doesnt exist in Firebug I believe, and the underlying problem is lack of support or lack of exposure at the api level. Alternatively, there's only a few ways to subscribe to DOM events: Element.prototype.addEventListener (and window.addEventListener and document.addEventListener and XMLHttpRequest.addEventListener and some others) aside from 'onevent' properties which are observable and interceptable.
But realistically, the WebKit debugger and Chromium's debugger (which is webkit's with extra points) allow one to debug and observe attached listeners. Sometimes it's easier to debug one browsers's bugs in another browser with better exposure of application/runtime state, even when that browser doesn't exhibit the bug.
https://developers.google.com/chrome-developer-tools/docs/elements
Event Listener Breakpoints have been introduced in FF 69 (and further improved in FF 71). Relevant docs are here.
It allows you to automatically break on any event of a given type. This screenshot (from above article) shows how it breaked on a Keyboard event:
The article further explains (1) how instead of breaking every time, it can just log matching events, and (2) how you can blackbox certain sources, to avoid having to wade through the internals of framework code (such as jquery, react etc.).
They present another screenshot of how that looks like:
Does anyone know if the onbeforeunload event is supported on the iPad and/or if there's a different way to use it?
I've tried pretty much everything, and it seems like the onbeforeunload event is never triggered on the iPad (Safari browser).
Specifically, this is what I've tried:
window.onbeforeunload = function(event) { event.returnValue = 'test'; }
window.onbeforeunload = function(event) { return 'test'; }
(both of the above together)
window.onbeforeunload = function(event) { alert('test')'; }
(all of the above functions but inside <body onbeforeunload="...">
All of these work on FF and Safari on the PC, but not on the iPad.
Also, I've done the following just after loading the page:
alert('onbeforeunload' in window);
alert(typeof window.onbeforeunload);
alert(window.onbeforeunload);
Respectively, the results are:
true
object
null
So, the browser does have the property, but for some reason it doesn't get fired.
The ways I try to navigate away from the page are by clicking the back and forward buttons, by doing a google search in the top bar, by changing location in the address bar, and by clicking on a bookmark.
Does anyone have any idea about what's going on? I'd greatly appreciate any input.
Thanks
This bit of JavaScript works for me on Safari and Chrome on ipad and iphone, as well as desktop/laptop/other browsers:
var isOnIOS = navigator.userAgent.match(/iPad/i)|| navigator.userAgent.match(/iPhone/i);
var eventName = isOnIOS ? "pagehide" : "beforeunload";
window.addEventListener(eventName, function (event) {
window.event.cancelBubble = true; // Don't know if this works on iOS but it might!
...
} );
I have found that the onunload() event does fire. It's behavior is somewhat odd; whatever you have in your callback function attached to the event is actually run after the new page has loaded in the background (You can't tell it's loaded yet, but server logging will show that it has).
More oddly, if you have a confirm() call in your onunload(), and the user has clicked a link to go somewhere else, you are in business. If, however, the user closes the iPad Safari browser tab, the onunload() event will fire, but your confirm() will have an implicit cancel as response.
Only Apple would know for sure, but my guess is that they purposely did not enable that functionality in mobile Safari because it is most often used by shady characters to get you to stay on their site or pop up lots of porn/advertising windows.
There's a known bug in WebKit with onbeforeunload. I believe it's fixed in the latest beta of Chrome 5, but it's quite possible the iPad's browser is made from a version of WebKit that doesn't have the fix.
Related Chrome bug report.
beforeunload event is not supported by Mobile Safari. You can see the list of all supported events here: Handling Events Apple documentation
And the beforeunload is not in the list!
https://code.google.com/p/chromium/issues/detail?id=97035
see hear.
alerts are no longer allowed during page dismissal events (beforeunload, unload, pagehide).
I think alerts, prompt, confirm, and other actions like these are also no longer allowed.
Here's a solution that should work on all modern browsers:
var unloaded = false;
window.addEventListener("beforeunload", function(e)
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
});
window.addEventListener("visibilitychange", function(e)
{
if (document.visibilityState == 'hidden')
{
if (unloaded)
return;
unloaded = true;
console.log("beforeUnload");
}
});
Mobile browsers don't tend to not support beforeunload because the browser can go into the background without unloading the page, then be killed by the operating system at any time.
Most desktop browser contain a bug that causes visibilityState to not get called when the document unloads. See: here.
Therefore, it's important to include both events to cover all scenarios.
NB
I have used console.log instead of alert in my example because alert will get blocked by some browsers when called from beforeunload or visibilitychange.
If you just need to know if the page has been left you can use document.unload. It works fine in ios browsers. If you see on Apple documentation you'll find that it's deprecated and they recommend to use document.pagehide