window.onbeforeunload可能会多次触发
Stack Exchange网络,GMail,Grooveshark,Yahoo! Mail和Hotmail使用onbeforeunload提示来阻止/警告用户在开始编辑内容后离开页面。哦,是的,几乎每一个桌面程序都接受可保存的用户输入数据,利用这个提示用户离开前的UX模式。
The Stack Exchange network, GMail, Grooveshark, Yahoo! Mail, and Hotmail use the onbeforeunload prompt to prevent/warn users that they are leaving a page after they have begun editing something. Oh yah, nearly every single desktop program that accepts saveable user-input data utilizes this prompt-user-before-leaving UX pattern.
我的函数与此函数类似:
I have a function which behaves similarly to this one:
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true){
return "Are you sure you want to leave this page?";
}
}
当用户尝试导航离开页面浏览器时向他们提供离开或留在页面上的选项。如果用户选择保留此页面选项,然后他们会在页面完全卸载之前再次快速单击链接,则会再次触发对话框。
When a user attempts navigates away from the page the browser presents them with the option to leave or stay on the page. If the user selects the "Leave this page option" and then they quickly click on a link again before the page unloads completely the dialog fires again.
是否有任何万无一失的解决方案这个问题?
Are there any foolproof solutions to this problem?
注意:以下不是解决方案:
Note: The following NOT the solution:
var alreadyPrompted = false;
window.onbeforeunload = function(){
// only prompt if the flag has been set...
if(promptBeforeLeaving === true && alreadyPrompted === false){
alreadyPrompted = true;
return "Are you sure you want to leave this page?";
}
}
因为用户可能选择留在页面上将导致未来 onbeforeunload
s停止工作的选项。
because the user might select the "Stay on the page" option which would cause future onbeforeunload
s to stop working.
我认为你可以通过在 onbeforeunload
回调中开始的计时器( setInterval
)来实现这一目标。在确认对话框启动时,Javascript执行将暂停,如果用户取消,则定时功能可以将已提示
变量重置为false,并清除间隔。
I think you could accomplish this with a timer (setInterval
) that starts in the onbeforeunload
callback. Javascript execution will be paused while the confirm dialog is up, then if the user cancels out the timed function could reset the alreadyPrompted
variable back to false, and clear the interval.
只是一个想法。
好的我根据你的评论进行了快速测试。
Ok I did a quick test based on your comment.
<span id="counter">0</span>
window.onbeforeunload = function () {
setInterval(function () { $('#counter').html(++counter); }, 1);
return "are you sure?";
}
window.onunload = function () { alert($('#counter').html()) };
在两个回调之间 #counter
从不高于2(ms)。似乎结合使用这两个回调可以满足您的需求。
In between the two callbacks #counter
never got higher than 2 (ms). It seems like using these two callbacks in conjunction gives you what you need.
编辑 - 回复评论:
关闭。这就是我的想法
var promptBeforeLeaving = true,
alreadPrompted = false,
timeoutID = 0,
reset = function () {
alreadPrompted = false;
timeoutID = 0;
};
window.onbeforeunload = function () {
if (promptBeforeLeaving && !alreadPrompted) {
alreadPrompted = true;
timeoutID = setTimeout(reset, 100);
return "Changes have been made to this page.";
}
};
window.onunload = function () {
clearTimeout(timeoutID);
};