Internet Explorer 在 window.open 和 AJAX 调用上调用 window.onbeforeunload

发布于 2024-08-09 20:02:15 字数 334 浏览 9 评论 0原文

好的,我在这个问题上花了一段时间,这就是我收集到的:

  1. 如果您在 IE7 中进行 AJAX 调用并且指定了 window.onbeforeunload 函数,它将调用 onbeforeunload 函数。

  2. 如果您尝试使用 window.open 打开一个新窗口而不干扰当前窗口,则会调用 onbeforeunload。

    如果您尝试使用 window.open

有谁知道如何阻止这个?我什至尝试将变量设置为 TRUE 并在 onbeforeunload 函数中检查该变量,但它仍然不起作用!我只需要能够停止 AJAX 调用和新窗口调用的该方法的执行。

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 method for AJAX calls and new window calls.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

鱼忆七猫命九 2024-08-16 20:02:15

另一个可能更简单的选项是在打开弹出窗口时返回 false:

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

这似乎可以阻止 IE 认为您正在离开页面并触发事件。所有其他选择对我来说都不是特别可行。

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.

酒与心事 2024-08-16 20:02:15

好的,我一直遇到这个问题。我有一个(相当混乱的)解决方法。

就我而言,我有时想阻止导航,而不是其他人。

因此,我在窗口上设置一个标志来告诉我是否要阻止它。因此,在执行 window.open 之前,执行“window.allowExit=true”,然后在 onbeforeunload 中检查 window.allowExit = true。

我从一个链接启动了java脚本(SHowHelp):

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

onbeforeunload在ShowHelp之前被调用,所以我使用onclick将标志

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

Ugly设置为sin,但它似乎有效!

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!

很酷不放纵 2024-08-16 20:02:15

这不是一个解决方案,而是对任何感兴趣的人的解释。我刚刚在 IE 7 中运行了一个快速测试,只要单击链接,它就会触发 onebeforeunload 事件,除非 HREF 位于同一页面上的某个位置:即除非它包含 #。所以我的猜测是,IE 工程师认为,当有人单击不在页面上其他位置的链接时,他们一定会离开该页面,在这种情况下,该页面即将卸载。不用说,这种想法存在明显的问题。

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.

君勿笑 2024-08-16 20:02:15

我认为您只需要在执行任何操作之前取消设置 window.onbeforeunload 函数,然后在完成后将其放回去。

我刚刚在 IE 中禁用了该功能。

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.

半枫 2024-08-16 20:02:15

我遇到了同样的问题,在我的情况下,所有请求都来自 ajax 调用,这简化了解决方案,因为当我使用标准按钮修复问题时,我执行了一个递归函数将所有 onclick 重定向到我的集中函数,然后消除正确的单击。
我也在复制 ajax 调用支持 href 问题的解决方案。
此解决方案避免返回到上一页。将代码放入名为 backbutton,js 的文件中
任何评论写入 [email protected],主题为:javascript backbutton

<!--  backbutton developed by Manuel Parma 2011-06-10 -->
<!--  email: [email protected] -->
<!--  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;
}

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 [email protected] with subject: javascript backbutton

<!--  backbutton developed by Manuel Parma 2011-06-10 -->
<!--  email: [email protected] -->
<!--  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;
}
嗳卜坏 2024-08-16 20:02:15

Sid_M 说得有道理,根据浏览器的设计,我们必须相应地设计我们的应用程序。

为什么要选择锚标签和标签? href 对于弹出窗口,只需在标签甚至 td 标签中使用 onclick 方法并调用 window.open

我的应用程序之一的简单示例

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

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>
孤独难免 2024-08-16 20:02:15

在调用 window.open 之前,您是否尝试从“onbeforeunload”事件中删除处理程序?这可以提供帮助,但我从未测试过。

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

迟月 2024-08-16 20:02:15

这很有可能解决您的问题!

因为我也遇到了类似的问题,所以一切顺利!

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

每当我执行 Ajax 调用或弹出另一个窗口时,我只需将 warnRequired 设置为 false。

另一件事是在进行 Ajax 调用时要注意它是同步的,否则变量可能尚未设置! (一个令人讨厌的陷阱!)

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!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文