天道酬勤,学无止境

Prevent a webpage from navigating away using JavaScript

Question

How to prevent a webpage from navigating away using JavaScript?

Answer1

Using onunload allows you to display messages, but will not interrupt the navigation (because it is too late). However, using onbeforeunload will interrupt navigation:

window.onbeforeunload = function() {
  return "";
}

Note: An empty string is returned because newer browsers provide a message such as "Any unsaved changes will be lost" that cannot be overridden.

In older browsers you could specify the message to display in the prompt:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}
Answer2

Unlike other methods presented here, this bit of code will not cause the browser to display a warning asking the user if he wants to leave; instead, it exploits the evented nature of the DOM to redirect back to the current page (and thus cancel navigation) before the browser has a chance to unload it from memory.

Since it works by short-circuiting navigation directly, it cannot be used to prevent the page from being closed; however, it can be used to disable frame-busting.

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

Disclaimer: You should never do this. If a page has frame-busting code on it, please respect the wishes of the author.

Answer3

I ended up with this slightly different version:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

Elsewhere I set the dirty flag to true when the form gets dirtied (or I otherwise want to prevent navigating away). This allows me to easily control whether or not the user gets the Confirm Navigation prompt.

With the text in the selected answer you see redundant prompts:

enter image description here

Answer4

The equivalent in a more modern and browser compatible way, using modern addEventListener APIs.

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

Source: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload

Answer5

In Ayman's example by returning false you prevent the browser window/tab from closing.

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}
Answer6

The equivalent to the accepted answer in jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

JSFiddle example

altCognito's answer used the unload event, which happens too late for JavaScript to abort the navigation.

Answer7

Use onunload.

For jQuery, I think this works like so:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});
Answer8

That suggested error message may duplicate the error message the browser already displays. In chrome, the 2 similar error messages are displayed one after another in the same window.

In chrome, the text displayed after the custom message is: "Are you sure you want to leave this page?". In firefox, it does not display our custom error message at all (but still displays the dialog).

A more appropriate error message might be:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

Or stackoverflow style: "You have started writing or editing a post."

Answer9

If you are catching a browser back/forward button and don't want to navigate away, you can use:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

Otherwise, you can use the beforeunload event, but the message may or may not work cross-browser, and requires returning something that forces a built-in prompt.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.

相关推荐
  • Full webpage and disabled zoom viewport meta tag for all mobile browsers
    Question I want my webpage to be full screen and disable zooming on all mobile devices. With the meta tag: <meta name="viewport" content="width=1165, user-scalable=no"> I am able to do this for iPhone/iPad, but on Android devices the website is zoomed in to about 125%. If I use the tag <meta name="viewport" content="width=max-device-width, user-scalable=no"> I get the opposite result. So then it works on Android but it doesn't work on iPad/iPhone. Answer1 Unfortunately each browser has it's own implementation of the viewport meta tag. Different combinations will work on different browsers
  • How can I prevent the backspace key from navigating back?
    Question On IE I can do this with the (terribly non-standard, but working) jQuery if ($.browser.msie) $(document).keydown(function(e) { if (e.keyCode == 8) window.event.keyCode = 0;}); But is it possible to do in a way which works on Firefox, or in a cross-browser way for a bonus? For the record: $(document).keydown(function(e) { if (e.keyCode == 8) e.stopPropagation(); }); does nothing. $(document).keydown(function(e) { if (e.keyCode == 8) e.preventDefault(); }); solves the problem, but renders the backspace key unusable on the page, which is even worse than the original behaviour. EDIT: The
  • Easiest way to open a download window without navigating away from the page
    Question What is the best cross browser way to open a download dialog (let's assume we can set content-disposion:attachment in the headers) without navigating away from the current page, or opening popups, which doesn't work well in Internet Explorer(IE) 6. Answer1 7 years have passed and I don't know whether it works for IE6 or not, but this prompts OpenFileDialog in FF and Chrome. var file_path = 'host/path/file.ext'; var a = document.createElement('A'); a.href = file_path; a.download = file_path.substr(file_path.lastIndexOf('/') + 1); document.body.appendChild(a); a.click(); document.body
  • How do I redirect to another webpage?
    Question This question's answers are a community effort. Edit existing answers to improve this post. It is not currently accepting new answers or interactions. How can I redirect the user from one page to another using jQuery or pure JavaScript? Answer1 One does not simply redirect using jQuery jQuery is not necessary, and window.location.replace(...) will best simulate an HTTP redirect. window.location.replace(...) is better than using window.location.href, because replace() does not keep the originating page in the session history, meaning the user won't get stuck in a never-ending back
  • How to show the “Are you sure you want to navigate away from this page?” when changes committed?
    Question Here in stackoverflow, if you started to make changes then you attempt to navigate away from the page, a javascript confirm button shows up and asks: "Are you sure you want to navigate away from this page?" blee blah bloo... Has anyone implemented this before, how do I track that changes were committed? I believe I could do this myself, I am trying to learn the good practices from you the experts. I tried the following but still doesn't work: <html> <body> <p>Close the page to trigger the onunload event.</p> <script type="text/javascript"> var changes = false; window.onbeforeunload =
  • Alerts when navigating away from a web page
    Question When I try to close my Google docs tab with unsaved changes, this is what I get in my browser (FF 3.5). Are you sure you want to navigate away from this page? You have unsaved changes in this document. Click Cancel now, then 'Save' to save them. Click OK now to discard them. Press OK to continue, or Cancel to stay on the current page. My question is whether such alerts are part of the web app (gdocs for eg.) or are they given out by the browser? If latter, how is this done? Answer1 By the browser. It's the beforeunload event handler that returns the customized text of the dialog
  • Prevent BACKSPACE from navigating back with jQuery (Like Google's Homepage)
    Question Notice while on Google's homepage, with no focus on any element, pressing BACKSPACE will put the focus into the search toolbar instead of navigating back. How can I accomplish this? I keep running into this problem with users in my app. They don't have focus on any element and hit BACKSPACE which throws them out of the app. Answer1 I would bind an event handler to keydown and prevent the default action of that event if we're dealing with the backspace key outside of a textarea or input: $(document).on("keydown", function (e) { if (e.which === 8 && !$(e.target).is("input, textarea")) {
  • How do I stop a page from unloading (navigating away) in JS?
    Question Does anyone know how to stop a page from reloading or navigating away? jQuery(function($) { /* global on unload notification */ warning = true; if(warning) { $(window).bind("unload", function() { if (confirm("Do you want to leave this page") == true) { //they pressed OK alert('ok'); } else { // they pressed Cancel alert('cancel'); return false; } }); } }); I am working on an e-commerce site at the moment, the page that displays your future orders has the ability to alter the quantities of items ordered using +/- buttons. Changing the quantities this way this doesn't actually change
  • Alert when browser window closed accidentally
    Question I have a chat application, I want that whenever user accidentally or manually closes the browser ,he should get an alert so that various clean up operations could be carried out. I have more thing i itried to use on before event but I want that to be used for a particular web page as all other web pages are also called on before load. Please help Answer1 We should prevent or prompt user that on performing these actions he will lose his data. Click on back browser button. Click on refresh browser button. Click on close button of browser. Click of forward browser button. Keyboard stroke
  • Refreshing Web Page By WebDriver When Waiting For Specific Condition
    Question I'm looking for more elegant way to refresh webpage during tests (I use Selenium2). I just send F5 key but I wonder if driver has method for refreshing entire webpage Here is my code while(driver.findElements(By.xpath("//*[text() = 'READY']")).size() == 0 ) driver.findElement(By.xpath("//body")).sendKeys(Keys.F5); //element appear after text READY is presented driver.findElement(By.cssSelector("div.column a")).click(); Maybe is some better solution for finding element on manually refreshed page Answer1 In Java or JavaScript: driver.navigate().refresh(); This should refresh page
  • create screenshot of webpage using html2canvas (unable to initialize properly)
    Question I am attempting to use http://html2canvas.hertzen.com/ to take screenshots of my webpage. I am unable to initialize a canvas element using... var canvas = $('body').html2canvas(); If I were able to get a proper canvas I would follow with something like var dataUrl = canvas.toDataURL(); //get's image string window.open(dataUrl); // display image Unfortunately, the documentations is very limited IMO. http://html2canvas.hertzen.com/documentation.html . I do not believe I need to preload as I am not using any dynamic graphics(but am not even getting that far anyways) I am simply too noob
  • Disable Browser Window Resize
    Question For starters... I have no sinister intention of subjecting users to popups or anything like that. I simply want to prevent a user from resizing the browser window of a webpage to which they've already navigated (meaning I don't have access to / don't want to use window.open();). I've been researching this for quite a while and can't seem to find a straightforward answer. I felt like I was on track with something along the lines of: $(window).resize(function() { var wWidth = window.width, wHeight = window.height; window.resizeBy(wWidth, wHeight); }); ...to no avail. I have to imagine
  • How can I close a browser window without receiving the “Do you want to close this window” prompt?
    Question How can I close a browser window without receiving the Do you want to close this window prompt? The prompt occurs when I use the window.close(); function. Answer1 window.open('', '_self', ''); window.close(); This works for me. Answer2 Scripts are not allowed to close a window that a user opened. This is considered a security risk. Though it isn't in any standard, all browser vendors follow this (Mozilla docs). If this happens in some browsers, it's a security bug that (ideally) gets patched very quickly. None of the hacks in the answers on this question work any longer, and if
  • How can I export tables to Excel from a webpage [closed]
    Question Closed. This question is opinion-based. It is not currently accepting answers. Want to improve this question? Update the question so it can be answered with facts and citations by editing this post. Closed 7 years ago. Improve this question How can I export tables to Excel from a webpage. I want the export to contain all the formatting and colours. Answer1 Far and away, the cleanest, easiest export from tables to Excel is Jquery DataTables Table Tools plugin. You get a grid that sorts, filters, orders, and pages your data, and with just a few extra lines of code and two small files
  • How to prevent IFRAME from redirecting top-level window
    Question Some websites have code to "break out" of IFRAME enclosures, meaning that if a page A is loaded as an IFRAME inside an parent page P some Javascript in A redirects the outer window to A. Typically this Javascript looks something like this: <script type="text/javascript"> if (top.location.href != self.location.href) top.location.href = self.location.href; </script> My question is: As the author of the parent page P and not being the author of the inner page A, how can I prevent A from doing this break-out? P.S. It seems to me like it ought to be a cross-site security violation, but it
  • Submit two forms with one button
    Question I have HTML two forms, one that submits data upon entry to a database using PHP, the other directs the user to a paypal payment page, my problem is that the user would have to submit both forms which of course I do not want them to have to do. Is there anyway to use one submit button for two forms? (Javascript is welcome) Answer1 You should be able to do this with JavaScript: <input type="button" value="Click Me!" onclick="submitForms()" /> If your forms have IDs: submitForms = function(){ document.getElementById("form1").submit(); document.getElementById("form2").submit(); } If your
  • javascript capture browser shortcuts (ctrl+t/n/w)
    Question Is it possible to capture these shortcuts? Ctrl+N Ctrl+T Ctrl+W I tried this but it doesn't work: $(window).keydown(function(event) { console.log(event.keyCode); event.preventDefault(); }); When I press T it shows 84 in the console, but if I press Ctrl+T it shows nothing, and opens a new tab. I would like to capture these shortcuts and prevent any browser action. Answer1 Capturing Ctrl keyboard events in Javascript Sample code: $(window).keydown(function(event) { if(event.ctrlKey && event.keyCode == 84) { console.log("Hey! Ctrl+T event captured!"); event.preventDefault(); } if(event
  • C# WebBrowser Ajax call
    Question I am using a WebBrowser control embedded in a C# WPF .NET4 app. Whenever I press manually the button in a form, the browser hangs on "Your request is being processed" message and nothing happens. If I do the same in full IE browser, the page is processed normally producing the results. What am I missing? The code behind the button: <a onclick="startSearch();" href="javascript:void(-1);" name="btnNext" class="btn floatLe noClear btnSubmit btnRight"> <span>Continue</span> </a> Answer1 WebBrowser control (both WPF and WinForms versions) behaves in many ways differently from the full IE
  • How do I access an iframe from CasperJS?
    Question I have a webpage with an iframe. I'd like to access the contents of the iframe using CasperJS. In particular, I need to click buttons and fill a form. How can I do that? The main webpage is main.html: <html><body> <a id='main-a' href="javascript:console.log('pressed main-a');">main-a</a> <iframe src="iframe.html"></iframe> <a id='main-b' href="javascript:console.log('pressed main-b');">main-b</a> </body></html> The iframe is: <html><body> <a id='iframe-c' href="javascript:console.log('pressed iframe-c');">iframe-c</a> </body></html> My naïve approach: var casper = require('casper')
  • Take a screenshot of a webpage with JavaScript?
    Question Is it possible to to take a screenshot of a webpage with JavaScript and then submit that back to the server? I'm not so concerned with browser security issues. etc. as the implementation would be for HTA. But is it possible? Answer1 I have done this for an HTA by using an ActiveX control. It was pretty easy to build the control in VB6 to take the screenshot. I had to use the keybd_event API call because SendKeys can't do PrintScreen. Here's the code for that: Declare Sub keybd_event Lib "user32" _ (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As