简体   繁体   中英

Can I prevent window.onbeforeunload from being called when doing an AJAX call

I have an AJAX-based grid control.

We hook into the window.onbeforeunload event to check if they have unsaved data and if so present them with a message "Are you sure you want to navigate away...you have unsaved data...".

All this is good.

But AJAX calls also trigger window.onbeforeunload and so if the grid has unsaved data and we make an AJAX call (such as to delete a row in another grid) the user gets the "Are you sure you want to navigate away...you have unsaved data..." message which is not good.

Is it possible to suppress the onbeforeunload event for AJAX calls? Or is it possible to detect that a call is an AJAX call? Otherwise we'll have to get hacking!

Thanks

If you want to trigger your postback by a hyperlink, there is a simple workaround: Instead of

<a href="javascript:submitFunction();">Submit</a>

or

<a href="javascript:;" onclick="submitFunction();">Submit</a>

just use this code:

<a href="#" onclick="submitFunction();">Submit</a>

It seems that IE fires the onbeforeunload event if the content of the href-attribute of a hyperlink is not the current page (which the sharp character indicates).

I did something like this:

inside body tag:

  var allowConfirm = true;

  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    if(allowConfirm)
        return "Are you sure you want to navigate away from this page?";
    else
        allowConfirm = true;
  }

When I Logout, I call this script:

allowConfirm = false; return window.location.href;

This is really weird, are you sure your Ajax call isn't loading a new link?

Be sure you read this relevant specification: onbeforeunload spec

See if the Ajax call maybe triggers any of the actions listed in the To invoke table.

In the case of IE6 or href you can hook the postback function. ie: if the postback function is WebForm_DoPostBackWithOptions and using Jquery , add this code below to code above

var DoPostBackWithOptionsHook = null;

$(document).ready(function(){
  DoPostBackWithOptionsHook = WebForm_DoPostBackWithOptions;
  WebForm_DoPostBackWithOptions = WebForm_DoPostBackWithOptionsHook;
}

function WebForm_DoPostBackWithOptionsHook(options) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
       if (navigateAwayFlag.length > 0) {
           navigateAwayFlag[0].value = "false"; }

    return DoPostBackWithOptionsHook(options)
}

解决此问题的一种方法是使用jquery在超链接标记的click事件上调用submitFunction(),并从超链接中删除href属性。

If you're talking about ASP.NET AJAX partial postbacks, then I encountered this behavior today too, doing the exact same thing. (If you're not, ignore my post completely.)

In my experience so far, it seems like if your partial postback is triggered by an input , it won't fire onbeforeunload during a partial postback, but if the partial postback is triggered by a hyperlink , it will. It seems like the browser assumes you're navigating away if you click on anything in an anchor tag (only tested in IE and FireFox but yeah).

Whether or not the page has a certain hidden field is already what I was using to determine client-side when it's appropriate to show the navigate away warning, so I was able to fix this very simply by adding a check of the hidden field's value to my onbeforeunload's if condition, and hooking into the PageRequestManager's BeginRequest and EndRequest handlers to set the value. That effectively disables the warning during partial postbacks. You could add more complicated logic here if there were more specific things you wanted to check.

Here's a really over-simplified code sample. (sorry if i pared and censored to the point where it doesn't work but it should give you an idea.)

window.onbeforeunload = checkNavigateAway;

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onBeginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest);

function onBeginRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "false";
    }
}

function onEndRequest(sender, args) {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0) {
        navigateAwayFlag[0].value = "true";
    }
}

function checkNavigateAway() {
    var navigateAwayFlag = $("input[id*='navigateAwayValue']");
    if (navigateAwayFlag.length > 0 && navigateAwayFlag[0].value == "true")
    {
        return "Warning Text";
    }
}

Edit : Bad news. The above doesn't seem to work in IE6. It seems like it fires events in a different order than Firefox, so the onbeforeunload fires before the AJAX beginRequest... May have to find a way to change the flag's value via the hyperlink click before the onbeforeunload fires.

这是不可能的,没有办法找出浏览器的刷新按钮是否被按下。

这实际上有效:

 OnClientClick="eval(this.href);return false" 

Not using AJAX, but still wanted to prevent leaving page with unsaved changes. I tried most of the prior suggestions, including navigateAway. None of them worked with IE 8. NavigateAway always returned length of 0.

I did find a blog on that had solution about using class as ID in tag and then setting Boolean based upon that. I tried that, but it doesn't work because .NET when it outputs the HTML was wrapping the input tag in a span tag with the class declared in it. My final solution was to put the word Ignore in the ID name of the tag. Also, to prevent onbeforeunload being called before click is trapped by code that sets the Boolean, one must use , such as asp:Button or asp:Input. Finally, asp forces (of VS IDE does) the starting name to be the type of control; ID="Button_Save". Using asp: tags also prevents onbeforeunload from being called twice.

<script type="text/javascript" language="javascript">
 var stuffchanged = false
 var ignorenavigate = false

  $(document).ready(function () {


    //Detect whether the event source has "nonavigate" class specified
    $("a,input,img,checkbox,button").click(function () {
        var str = $(this).attr("ID");
        ignorenavigate = str.search("Ignore") > 0;
    });

});

window.onbeforeunload = confirmExit;
function confirmExit() {
    if (stuffchanged && !ignorenavigate) {
        return "You have attempted to leave this page with unsaved changes.  If you have made any changes to the fields without " +
    "clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
    }  

}

  function textchanged() {
     stuffchanged = true;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM