开发者

Internet Explorer calling window.onbeforeunload on window.open and AJAX calls

Ok, I have spent a while on this problem and this is what I have gathered:

  1. If you make an AJAX call in IE7 and you have a window.onbeforeunload function specified, it calls the onbeforeunload function.

  2. If you try to open a new window with window.open WITHOUT disturbing the current window, the onbeforeunload gets called.

Does anyone know how to stop this? I even tried setting a variable to TRUE and check that variable in my onbeforeunload function and it still dosent work! I just need to be able to stop the execution of that met开发者_如何学编程hod for AJAX calls and new window calls.


Another and probably simpler option is to return false when you open the popup:

<a onclick="window.open(...); return false;" href="javascript:;" >my link</a>

This seems to stop IE from thinking you're leaving the page and triggering the event. All the other options weren't particularly viable for me.


OK, I have been having this issue. I have a (rather messy) work around for it.

In my case, I want to block navigation away sometimes, and not others.

So, I am setting a flag on the window to tell me if I want it blocked. So where you are doing your window.open, just before that, do 'window.allowExit=true' then in the onbeforeunload, check for window.allowExit = true.

I have the java script (SHowHelp) being kicked off from a link:

<a href="javascript:ShowHelp('argument')" >HERE</a>

onbeforeunload is called BEFORE the ShowHelp, so i used the onclick to set the flag

<a onclick="window.allowExit = true;" href="javascript:ShowHelp('argument')" >HERE</a>

Ugly as sin, but it seems to work!


This is not a solution, but an explanation for anybody who is interested. I just ran a quick test in IE 7, and it fires the onebeforeunload event any time a link is clicked unless the HREF goes somewhere on the same page: i.e. unless it contains a #. So my guess is that the IE engineers were thinking that when somebody clicks a link that is not to somewhere else on the page, then they must be leaving the page, in which case the page is about to unload. Needless to say, there are obvious problems with this thinking.


I figured that you just need to unset the window.onbeforeunload function before you do anything and then put it back when you're done.

I just ended up disabling the feature in IE.


I had the same problem, in my case all request come from ajax call, this simplify the solution, because when I fixed the porblem with standard button I did a recursive function to redirect all onclick to my centralized function an then dispath the rigth click. I am copying the solution for ajax call suporting href problem too. This solution avoid to return to previous page. Put the code inside a file named backbutton,js Any comment write to mparma@usa.net with subject: javascript backbutton

<!--  backbutton developed by Manuel Parma 2011-06-10 -->
<!--  email: mparma@usa.net -->
<!--  Add the next line into the <body> section as a first line  -->
<!--  <script type="text/javascript" src="<path>/backbutton.js"></script> -->

<!-- Address used when backtoLogin is 1 or when there is not previous page from site -->
var returningAddress = "http://my returning address"

<!-- Message to display when an external action (back button, forward button, backspace) move without press the application buttons -->
var backButtonMessage = "Using the browser's Back button may cause a loss in data. Please use the Back and Continue buttons at the bottom of the form."

<!-- 0=no / 1=yes (assume per default that the back button will be pressed -->
<!--               and come into action if this was NOT the case)          -->
var backButtonPressed = 1;    

<!--This var when is setted to 1 avoid to captureEvent set backbuttonPressed to 1, otherwise unload event cannot detect the right state of backButtonPressed-->
var onbeforeunloadeventFired = 0;

<!--Indicate to logic back to first page (login) when its value is 1 otherwise the logic back to previous page out of the site-->
var backtoLogin = 0;
var DoPostBackWithOptionsHook = null;
var DoPostBackHook = null;


<!-- Check the previous status -->
if (window.name == ""){
    <!-- When window.name is empty, this is indicating the first call of site -->
    window.name = "L0001";
}
else { 
    if (window.name == "L0000_back"){
        <!-- In this condition the page is returning after a foward button press  -->
        setBackButton(0);
        window.name = "";

        <!-- the system reload the page to clean the data -->
        window.location.href = returningAddress;
    }
    else {
        if (window.name.indexOf("_back") > 4){
            <!-- when the word back is present, the previous call is sending a message that the back button was pressed and the site is going out -->

            <!-- get the internal counter -->
            var sLastValue = modifynamevalue(0);    

            <!-- set the count to go back -->
            var iCountBack = -(sLastValue * 1);
            if (backtoLogin == 1) {iCountBack++;};

            if (window.history.length - 2 < -iCountBack) {
                iCountBack = -(window.history.length - 2);
            }

            <!-- the site is flag that first page needs to reload -->
            window.name = "L0000_back";             
            setBackButton(0);

            <!-- the site is returning to the first page or previous -->
            window.history.go(iCountBack);
        }
        else {
            <!-- increase the internal counter -->
            var sLastValue = modifynamevalue(+1);
            window.name = "L" + sLastValue;
        }
    }
}

<!-- Set the events needed to manage the back and forwar button situations -->

$(document).ready(function(){
    if (typeof(Sys) == "object") {
        Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(beginRequest);
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(endRequest);

        window.onbeforeunload = onbeforeunloadEvent;
        window.onunload = unloadEvent;
        DoPostBackWithOptionsHook = WebForm_DoPostBackWithOptions;
        WebForm_DoPostBackWithOptions = WebForm_DoPostBackWithOptionsHook;

        doPostBackHook = __doPostBack;
        __doPostBack =  __doPostBackHook;

    }

    });

function WebForm_DoPostBackWithOptionsHook(options) {
    setBackButton(0);
    return DoPostBackWithOptionsHook(options)
}

function __doPostBackHook(eventTarget, eventArgument) {
    if (backButtonPressed == 1) {
        setBackButton(0);
    }
    return doPostBackHook(eventTarget, eventArgument)
} 

function beginRequest(sender, args) {
    setBackButton(0);
    <!-- setting onbeforeunloadeventFired = 1 I take care to avoid anyone changed the Backbutton until endrequest -->
    onbeforeunloadeventFired = 1;
}


function endRequest(sender, args) {
    onbeforeunloadeventFired = 0;
    setBackButton(1);
}

<!-- unload event handler -->
function unloadEvent(evt) {
    <!-- double coundition using onbeforeunloadeventFired == 1 garantee avoid problemas with redirect operations -->
    if ((backButtonPressed == 1) && (onbeforeunloadeventFired == 1)) {
        <!-- decrement the internal counter -->
        var sLastValue = modifynamevalue(-1);
        window.name = "L" + sLastValue + "_back";
    }

    if (DoPostBackWithOptionsHook !== null) {
        WebForm_DoPostBackWithOptions = DoPostBackWithOptionsHook;
    };

    if (doPostBackHook !== null) {
        __doPostBack = doPostBackHook;
    };
}

<!-- on before unload -->
function onbeforeunloadEvent(evt) {
    onbeforeunloadeventFired = 1;
    if (backButtonPressed == 1) {
        return backButtonMessage;
    };
}


<!-- used to set right backButtonPressed-->
function setBackButton(value){
    if (value == 0) {
        backButtonPressed = 0;
    }
    else {
        if (onbeforeunloadeventFired == 0) {
            backButtonPressed = 1;
        }
    }
}


<!-- increment and decrment the internal counter stored into windows.name -->
function modifynamevalue(iIncrement){
    var iCount = (window.name.substring(1, 5) * 1) + iIncrement;

    if (iCount < 0) {
        iCount = 0;
    }

    var sNewValue = iCount.toString();

    sNewValue = "0000".substring(0, 4 - sNewValue.length) + sNewValue;
    return sNewValue;
}


Sid_M said a valid point, with that design of browser we have to design our application accordingly.

Why to go for anchor tag & href for popup windows, just use onclick method in label or even td tag and call window.open

Simple example from one of my application

<td class="popuplink" onMouseOver="this.style.cursor='hand'" onclick="javascript:openMe('img/howitworks.png', 'pndpopup', 600,650)"><u> How it works</u></td>


did you try removing handler from "onbeforeunload" event before calling to window.open? This can help but I never tested it.


This could very possible solve your problem!

Because I had a similar issue and this made go way!

window.onbeforeunload = warnFunction;
var warnRequired = true;
function warnFunction () {
    if (warnRequired) return ("Please Stay! Don't go!");
    return ;
}

And whenever I do a Ajax call or Popup another window, I just set warnRequired to false.

One other thing just be aware when making an Ajax call that it is synchronized else the variable might not have been set yet! (A nasty Gotcha!)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜