22

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?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ivin
  • 4,435
  • 8
  • 46
  • 65

2 Answers2

36

According to this documentation, the popstate event is not cancellable:

Specification: HTML5
Interface: PopStateEvent
Bubbles: Yes
Cancelable: No
Target: defaultView
Default Action: None

Patrick Klug
  • 14,056
  • 13
  • 71
  • 118
  • No but you can do: window.onpopstate = function (ev) { ev.preventDefault(); history.go(1); }; – Sean Jul 10 '23 at 01:05
9

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);
 }
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
John
  • 1
  • 13
  • 98
  • 177
  • 52
    'Not possible' can most certainly be an answer – Rob Jul 22 '17 at 02:23
  • 6
    I filed a bug on Chrome about the backspace and made a strong case about high risk of data loss and you know what? They listened and took backspace as a back button out of Chrome. After all these years and all it took was to ask. Now if only YouTube would listen about the spacebar... – Zectbumo Nov 29 '17 at 12:16
  • 1
    related: call `e.stopImmediatePropagation()` to prevent subsequently-added popstate handlers from firing too. For instance, if a router listens to popstate and replaces content accordingly, you can prevent it from replacing content. – JohnnyFun Dec 05 '19 at 04:46
  • 2
    The text you insist on re-adding isn't appropriate; stop rolling back. – Zoe Feb 04 '22 at 09:56