Internet Explorer 在 window.open 和 AJAX 调用上调用 window.onbeforeunload
-
11-09-2019 - |
题
好吧,我花了一段时间来解决这个问题,这是我收集到的:
如果您在 IE7 中进行 AJAX 调用并且指定了 window.onbeforeunload 函数,它将调用 onbeforeunload 函数。
如果您尝试使用 window.open 打开一个新窗口而不干扰当前窗口,则会调用 onbeforeunload 。
有谁知道如何阻止这个?我什至尝试将变量设置为 TRUE 并在 onbeforeunload 函数中检查该变量,但它仍然不起作用!我只需要能够停止 AJAX 调用和新窗口调用的该方法的执行。
解决方案
另一个可能更简单的选项是在打开弹出窗口时返回 false:
<a onclick="window.open(...); return false;" href="javascript:;" >my link</a>
这似乎阻止 IE 认为您正在离开页面并触发事件。所有其他选择对我来说都不是特别可行。
其他提示
好的,我一直遇到这个问题。我有一个(相当混乱的)解决方法。
就我而言,我有时想阻止导航,而不是其他人。
因此,我在窗口上设置一个标志来告诉我是否要阻止它。因此,在执行 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>
丑陋如罪,但似乎有效!
这不是一个解决方案,而是对任何感兴趣的人的解释。我刚刚在 IE 7 中运行了一个快速测试,只要单击链接,它就会触发 onebeforeunload 事件,除非 HREF 位于同一页面上的某个位置:IE。除非它包含#。所以我的猜测是,IE 工程师认为,当有人单击不在页面上其他位置的链接时,他们一定会离开该页面,在这种情况下,该页面即将卸载。不用说,这种想法存在明显的问题。
我认为您只需要在执行任何操作之前取消设置 window.onbeforeunload 函数,然后在完成后将其放回去。
我刚刚在 IE 中禁用了该功能。
我遇到了同样的问题,在我的情况下,所有请求都来自 ajax 调用,这简化了解决方案,因为当我使用标准按钮修复问题时,我执行了一个递归函数将所有 onclick 重定向到我的集中函数,然后消除正确的单击。我也在复制 ajax 调用支持 href 问题的解决方案。此解决方案避免返回到上一页。将代码放入名为BackButton的文件中,JS任何评论都会写给mparma@usa.net,并带有主题:JavaScript 后退按钮
<!-- 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 说得有道理,根据浏览器的设计,我们必须相应地设计我们的应用程序。
为什么要为弹出窗口选择锚标记和 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>
在调用 window.open 之前,您是否尝试从“onbeforeunload”事件中删除处理程序?这可以提供帮助,但我从未测试过。
这很有可能解决您的问题!
因为我也遇到了类似的问题,所以一切顺利!
window.onbeforeunload = warnFunction;
var warnRequired = true;
function warnFunction () {
if (warnRequired) return ("Please Stay! Don't go!");
return ;
}
每当我执行 Ajax 调用或弹出另一个窗口时,我只需将 warnRequired 设置为 false。
另一件事是在进行 Ajax 调用时要注意它是同步的,否则变量可能尚未设置!(一个令人讨厌的陷阱!)