I'm trying to stop the user from going back in my web app. For this I tried catching the window.onpopstate and added e.preventDefault to cancel the back button effect.
But it doesn't seems to happen.
window.addEventListener('popstate',function(e){
console.log(e); e.preventDefault();
});
Is it not possible to prevent the popstate event of browser? Or am I doing something wrong?
According to this documentation, the popstate event is not cancellable:
Specification: HTML5 Interface: PopStateEvent Bubbles:
Yes
Cancelable: No Target: defaultView Default Action: None
First off "not possible" is never an acceptable answer.
Secondly you can compensate for popstate bugs. In example my rich editor has to constantly compensate for the lazy-bastard key: Backspace. It's not a valid key for a back button (just like spacebar for "page downing") but people impose their personal preferences upon the world instead of adding a browser extension so when people press it sometimes the popstate is triggered instead of the editor removing whatever character is to the left of the keyboard caret.
The following code (dependencies in my platform's documentation) detects when the popstate bug is triggered, slaps it in the face with a e.preventDefault(); and then fixes the address bar address with history.go(1);. The person using the editor doesn't notice anything happened as the browser was not allowed to manipulate the DOM. This code is minimal (other people may be compensating for this bug in various contexts) and I've only tested this in Gecko/Firefox currently so be sure to test Blink, Presto, Trident and WebKit based browsers as well.
window.onpopstate = function(e)
{
if (id_('editor') && is_node_parent(document.activeElement,id_('editor')))
{
e.preventDefault();
history.go(1);
}
}
Related
Upon clicking the back button in the browser, I would like to prevent the default behaviour of going one page back and instead do an action. I'm using the "popstate" event listener. The following function (I'm using Vue 2) works in all major browsers and even in Firefox for Android, but when I test it in Chrome for Android, it simply goes back one page without popstate being triggered at all.
mounted() {
history.pushState(null, null, <current-url>);
window.addEventListener("popstate", () => { alert(1) });
}
I tried wrapping the popstate event inside the load event and giving it a timeOut of 0, but it still didn't work specifically in Chrome for Android. The version I'm testing on is 93.
I did some more research and it seems that Chrome won't let you use popstate if there is no user interaction first. As long as you click on something or scroll down on mobile, popsate will work, otherwise it won't. I tried to simulate user interaction with click(), but that didn't work either. It seems Chrome wants genuine user interaction. I also realized this is sort of a duplicate of: Chrome popstate not firing on Back Button if no user interaction
Is it possible to prevent the default action of the Escape key in an Electron app -- specifically, to prevent it from cancelling an in-progress drag and drop action in the Chrome window? See this fiddle for example -- if you drag and hold the div and then press the Esc key, the drag is cancelled, even though there is an event listener that calls e.preventDefault on the event: https://jsfiddle.net/82aL6gsy/
Does Electron (or Chrome) provide any lower-level or less restricted APIs that we can use to intercept this?
Update: please note that this question is about whether or not the mentioned functionality can be achieved, not about why or whether doing so would be a good idea.
After some investigation, I think the esc-cancels-drag-n-drop functionality may be implemented either as a special case within Chromium (although I couldn't find where), or as part of the desktop environment, in which case Chromium may not even see the event. In any case, there is no associated keydown event for the key press that cancels the drag, and I don't think there is any way to intercept this behaviour from JavaScript, even in Electron.
After a long day of trying to find a solution to this problem, I keep getting the same issue.
Basically, I have a site, if the user clicks on the "browser-refresh" button, I want to pop-up a "are you sure" alert box with the options "reload" and "don't reload" (Basically, what the browser returns).
Surprisingly, it works just fine in IE. But in chrome or firefox, the refresh happens normally without a popup.
The popup only appears if I click on the body some where and then click on the "browser-refresh" button.
I already the following and other many similar alternatives :
window.onbeforeunload = function (e) {
e = e || window.event;
// For IE and Firefox prior to version 4
if (e) {
e.returnValue = 'Any string';
}
// For Safari
return 'Any string';
};
I tried to simulate a click event on page load with 'trigger('click')', '.click()' events.
But, still doesn't work until I click on the body myself (physically).
I've created a short pen, which replicates the issue I'm facing.
https://codepen.io/kanchanrai/pen/LQEZYV
Any help would be very highly appreciated. Thanks in Advance.
Maybe a late answer...
Here is what MDN documentation on beforeunload event states:
Note: To combat unwanted pop-ups, browsers may not display prompts created in beforeunload event handlers unless the page has been interacted with, or may even not display them at all.
This matches the behavior you observed.
I would like for a button to react to 'touches' on a touch screen, and 'clicks' on a non-touch screen. In case of a touch screen, I only want the touchstart handler to direct my flow and prevent the system from further handling the click event.
For this, I added two event listeners to my button. One listens for touchstart events. Once a touchstart has been detected, it uses event.preventDefault() to cancel the click event.
The code below on a touchscreen in Chrome, Opera and Android browsers achieves the desired result:
- one alert saying "touch".
However, in Firefox both events are detected, in spite of the preventDefault() in the touchstart handler:
two alerts... first one says "touch", followed by a second alert saying "click".
lginButton.addEventListener('touchstart', function(event) {
event.preventDefault();
alert("touch");
}, false);
lginButton.addEventListener('click', function(event) {
alert("click");
}, false);
Why is this happening and how can I achieve the desired results in all browsers?
I am currently unable to test. But based on your feedback it appears that Firefox is in fact not following the spec on events found here. I was about to find 4-5 bug logs on Mozilla that discussed this very topic, and finally found one that resolved the issue here https://bugzilla.mozilla.org/show_bug.cgi?id=977226. Definitely check to make sure you have the current version of firefox. And if you do it may be worth opening a new bug with mozilla on this. In the meantime you can set up a conditional inside of your touchstart event handler that detects the event type and handles touch and mouse events differently.. And then further adding more conditionals within you click conditional to handle browser and OS version. which is super bad practice, but would keep you going until a patch was implemented.
Is there any way to prevent a key like F1 from being pressed?
After a short search, I found this website:
http://www.cambiaresearch.com/c4/789d4357-60e9-4dbd-8e8c-affb2ebd6960/How-Do-I-Suppress-a-Keystroke-in-a-Browser-Input-Box-Using-Javascript.aspx
This way one can suppress keys like 'a' being pressed (it does not get put in the textbox), but keys like 'tab', 'F1' etc. are still working, i.e. the focus does change and, as I'm using Google Chrome, the Chrome help website does pop up.
I'm specifically talking about Google Chrome; the solution does not have to work in other browsers too.
Is this possible at all, and if so, how?
Thanks.
keypress is not necessarily triggered when the keypress is not a character. So the browser may not trigger an event on backspace, F1, the down key, etc.
Try cancelling events on keydown instead:
element.addEventListener('keydown', function(e) {
if (e.which === 112) { // F1 pressed
e.preventDefault(); // cancel the event
}
}
Note that this will work in Chrome and other standards-compliant browsers, but not in Internet Explorer <9.
I highly doubt that this is possible. Not only would one be able to interfere normal program behaviour (say, F5 to refresh the page, or ALT+F4 to close the browser), but in a quick test it looks like for keys like F1 etc. no event is fired, so there is no way for a input to receive that.