9

仅仅因为您看不到某个功能的用途并不意味着它没有用。

Stack Exchange 网络、GMail、Grooveshark、Yahoo!Mail 和 Hotmail 使用 onbeforeunload 提示来防止/警告用户在开始编辑内容后他们将离开页面。哦,是的,几乎每一个接受可保存用户输入数据的桌面程序都使用了这种在离开前提示用户的 UX 模式。


我有一个与此类似的函数:

window.onbeforeunload = function(){
    // only prompt if the flag has been set... 
    if(promptBeforeLeaving === true){
        return "Are you sure you want to leave this page?";
    }
}

当用户尝试离开页面时,浏览器会为他们提供离开或留在页面上的选项。如果用户选择“离开此页面选项”,然后他们在页面完全卸载之前再次快速单击链接,则对话框再次触发。

这个问题有没有万无一失的解决方案?


注意:以下不是解决方案:

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?";
    }
}

因为用户可能会选择“留在页面上”选项,这会导致 futureonbeforeunload停止工作。

4

2 回答 2

6

我认为您可以使用在回调setInterval中启动的计时器 () 来完成此操作。onbeforeunloadJavascript 执行将在确认对话框启动时暂停,然后如果用户取消定时功能,则可以将alreadyPrompted变量重置为 false,并清除间隔。

只是一个想法。

好的,我根据您的评论进行了快速测试。

<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)。似乎结合使用这两个回调可以满足您的需求。

编辑 - 回答评论:

关闭。这就是我的想法

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);
};
于 2010-11-08T18:44:35.150 回答
1

我已经将上面的答案封装在一个易于使用的函数中:

function registerUnload(msg, onunloadFunc) {
    var alreadPrompted = false,
        timeoutID = 0,
        reset = function() {
            alreadPrompted = false;
            timeoutID = 0;
        };

    if (msg || onunloadFunc) { // register
        window.onbeforeunload = function() {
            if (msg && !alreadPrompted) {
                alreadPrompted = true;
                timeoutID = setTimeout(reset, 100);
                return msg;
            }
        };

        window.onunload = function() {
            clearTimeout(timeoutID);
            if (onunloadFunc) onunloadFunc();
        };
    } else { // unregister
        window.onbeforeunload = null;
        window.onunload = null;
    }
}

注册使用:

registerUnload("Leaving page", function() { /* unload work */ });

注销使用:

registerUnload();

希望这可以帮助 ..

于 2013-08-13T01:01:07.327 回答