如何知道用户是否在 Javascript onbeforeunload 对话框上单击了取消?

IT技术 javascript jquery dom-events onbeforeunload
2021-01-30 20:39:31

当有人试图离开特定页面而没有保存他们的工作时,我会弹出一个对话框。我使用 Javascript 的 onbeforeunload 事件,效果很好。

现在我想在用户点击出现的对话框上的“取消”时运行一些 Javascript 代码(说他们不想离开页面)。

这可能吗?我也在使用 jQuery,那么是否有我可以绑定到 beforeunloadcancel 之类的事件?

更新:如果他们选择取消,这个想法实际上是保存并引导用户到不同的网页

6个回答

你可以这样做:

$(function() {
    $(window).bind('beforeunload', function() {
        setTimeout(function() {
            setTimeout(function() {
                $(document.body).css('background-color', 'red');
            }, 1000);
        },1);
        return 'are you sure';
    });
}); 

setTimeout一种方法中的代码有 1 毫秒的延迟。这只是将函数添加到UI queue. 由于setTimeout异步运行,Javascript 解释器将通过直接调用return语句继续运行,进而触发浏览器modal dialog这将阻塞UI queue并且setTimeout不会执行第一个代码,直到模态关闭。如果用户按下取消,它将触发另一个 setTimeout,它会在大约一秒钟内触发。如果用户确认 ok,用户将重定向并且永远不会触发第二个 setTimeout。

示例:http : //www.jsfiddle.net/NdyGJ/2/

@ScottEvernden 我刚刚用两个最新版本的 Chrome 对其进行了测试,它可以工作(再次?)包括版本 40.0.2214.94
2021-03-13 20:39:31
@jAndy。当用户选择离开此页面选项时,也会触发 SetTimeOut。我们怎么能阻止它。
2021-03-23 20:39:31
这不适用于慢速连接:无论确认选择如何,都会调用第二次超时,并且可以在实际卸载之前执行(在受限制的 Chrome 上)。
2021-03-31 20:39:31
在 Chrome 64 中不起作用。它不希望您执行任何代码。我正在保存 onblur。如果您单击“重新加载”,它会保存,因为模糊被触发。如果您只是按 Enter,它不会触发 onblur,因此不会保存。
2021-04-02 20:39:31
截至 2014 年 1 月,此方法不适用于 chrome。
2021-04-12 20:39:31

我知道这个问题现在已经过时了,但是如果有人仍然对此有疑问,我找到了一个似乎对我有用的解决方案,

基本上unload事件是在beforeunload事件发生后触发的我们可以用它来取消beforeunload事件中创建的超时,修改jAndy的回答:

$(function() {
    var beforeUnloadTimeout = 0 ;
    $(window).bind('beforeunload', function()  {
        console.log('beforeunload');
        beforeUnloadTimeout = setTimeout(function() {
            console.log('settimeout function');
            $(document.body).css('background-color', 'red');
        },500);
        return 'are you sure';
    });
    $(window).bind('unload', function() {
        console.log('unload');
        if(typeof beforeUnloadTimeout !=='undefined' && beforeUnloadTimeout != 0)
            clearTimeout(beforeUnloadTimeout);
    });
}); 

编辑: jsfiddle在这里

我进行了更多测试,发现如果我放置大约 5 秒(而不是 0.5 秒),它会按预期工作。但我认为如果您取消对话就太过分了……太糟糕了,我们没有得到关于那个对话的任何更好的反馈。
2021-03-15 20:39:31
是的,这对我有用,请尝试增加超时功能的时间。
2021-03-18 20:39:31
这对你有用吗?因为在我的情况下,我unload在计时器功能执行后得到类似的方式......(我在 Firefox 35 中测试过)
2021-03-19 20:39:31
这是一个绝妙的主意。但是,它受到延迟的影响。在最坏的情况下,Web 服务器关闭,且 beforeunload 超时的长度必须等于浏览器的超时。
2021-03-23 20:39:31

不可能。也许有人会证明我错了...你想运行什么代码?你想在他们点击取消时自动保存吗?这听起来违反直觉。如果你还没有自动保存,我认为当他们点击“取消”时自动保存没有意义。也许您可以在 onbeforeunload 处理程序中突出显示保存按钮,以便用户在导航离开之前看到他们需要做什么。

这个想法是如果他们选择取消,实际上然后保存并引导他们到不同的网页。
2021-03-21 20:39:31

我不认为这是可能的,但只是尝试了这个想法并且它有效(尽管它是一种黑客行为,并且可能无法在所有浏览器中正常工作):

window.onbeforeunload = function () {   
  $('body').mousemove(checkunload);
  return "Sure thing"; 
};

function checkunload() {   
  $('body').unbind("mousemove");
  //ADD CODE TO RUN IF CANCEL WAS CLICKED
}
我想你可以在绑定 mousemove 事件之前添加一个超时,这可能会修复它,尽管这使它更像是一个黑客。
2021-03-20 20:39:31
现有窗口需要超过 1 秒才能消失,如果您移动鼠标,则看起来像是取消。有一个计时器与 jAndy 的答案有相同的缺点,这对我来说并不合适。
2021-03-27 20:39:31
如果您在单击确定离开站点后移动鼠标,无论如何都会运行“取消代码”...
2021-03-29 20:39:31

另一种变体 第一个 setTimeout 等待用户响应浏览器的离开/取消弹出窗口。第二个setTimeout等待1秒,然后CancelSelected只有在用户取消时才会调用。否则页面将被卸载并且 setTimeout 丢失。

window.onbeforeunload  = function(e) {
    e.returnValue = "message to user";
    setTimeout(function () { setTimeout(CancelSelected, 1000); }, 100);
}

function CancelSelected() {
    alert("User selected stay/cancel");
}
如果我刷新页面并选择退出并且新页面需要一些时间来加载,则会显示警报...不好
2021-03-16 20:39:31