【问题标题】:Capturing result of window.onbeforeunload confirmation dialogwindow.onbeforeunload 确认对话框的捕获结果
【发布时间】:2011-03-23 00:43:15
【问题描述】:

有没有一种方法可以捕获window.onbeforeunload 确认对话框的结果,如下面的 Stack Overflow 中的结果(这种情况发生在离开“”页面而不发布问题时)?

这就是它在 Chrome 中的显示方式,我相信它在其他浏览器中略有不同,但您总是有某种形式的是/否按钮。

如果他们在事件触发后仍然在违规页面上,他们会选择留下来,你可以通过观察 js 的顺序来解决这个问题。但是我想知道如何确定他们是否点击了“离开此页面”

我已经实现了如下:

// concept taken from SO implementation
function setConfirmUnload(showMessage, message) {
    window.onbeforeunload = showMessage ? (message ? message : "this is a default message") : null;
}

// pseudo code
listen to changes on inputs
if any inputs fire a change event
   call setConfirmUnload(true, 'My warning message')

注意我在我的网站中使用 jQuery。

我实际上是在尝试实现类似于 Gmail 的草拟实现,其中如果用户离开页面时使用了他们在未保存的情况下进行了更改的表单,他们会被类似的对话框所吸引。如果他们选择放弃他们所做的更改并离开页面,我需要从数据库中清理一些临时记录(我正在考虑 AJAX 调用,或者只是提交带有delete 标志的表单)然后发送它们他们的方式。

我的问题还涉及:

jQuery AJAX call in onunload handler firing AFTER getting the page on a manual refresh. How do I guarantee onunload happens first?

【问题讨论】:

    标签: javascript jquery dom-events onunload window.onunload


    【解决方案1】:

    您可以使用window.onbeforeunload 进行退出确认,但无法确定用户点击了哪个按钮。

    引用jvenema from this thread的较早回复:

    主要目的 beforeunload 用于类似的事情 允许用户选择保存 在更改丢失之前更改。

    此外,如果您的用户要离开, 已经太晚了[...]

    【讨论】:

    • 测试用户点击的内容:我使用window.onfocus()找到了一个成功的解决方案。该功能将在用户点击 STAY 时触发,并返回到页面。但是,请注意,在更改选项卡、窗口等时也会触发 onfocus()。在 onbeforeunload() 中设置一个全局变量,以便能够检查/捕获用户来自哪里。如果用户确实想离开页面,你可以在window.onunload()做一些最后的事情
    • window.onfocus 技巧在 Firefox 和 Chrome 中对我(仅 IE)不起作用,但我发现在“beforeunload”处理程序中使用 setTimeout(如果用户选择调用运行一些代码)留在页面上)工作。你可以在这里看到一个工作示例:jsfiddle.net/nathanbedford/uscobrm0/10
    • 我发现在firefox 75.0中刷新页面时这两种方法都不起作用(可靠),超时似乎起作用,但它必须设置为比页面的重新加载时间更长。我对其进行了测试,有时会触发一秒钟的超时,从而影响重新加载的页面。
    • 进行了更多挖掘,发现超时必须设置为比用户需要下定决心的时间更长,因为计时器将继续在后台运行。
    【解决方案2】:

    这个怎么样:

    $( window ).bind( 'beforeunload' , function( event ) {
        setTimeout( function() {
            alert( 'Hi againe!' );
        } );
        return '';
    } ).bind( 'unload', function( event ) {
        alert( 'Goodby!' );
    } );
    

    【讨论】:

    • 这并没有真正削减它......即使在本地主机上,beforeunloadunload 之间也需要一个以上的滴答声。在慢速连接上,即使是 500 毫秒的延迟也可能太短。
    【解决方案3】:

    聚会迟到了,但我发现以下代码(在 TypeScript 中)是一种很好的方式来检测该人是否在该确认对话窗口上单击了“确定”。

    public listenToUnloadEvents(): void {
    
      window.addEventListener('beforeunload', (e) => {
        const confirmationMessage = '\o/';
    
        (e || window.event).returnValue = confirmationMessage;     // Gecko + IE
        return confirmationMessage;                                // Webkit, Safari, Chrome etc.
      });
    
      window.addEventListener('unload', () => {
    
        this.sendNotification(Action.LEFT)
      });
    }
    

    我不确定在unload 事件中运行代码需要多少时间,但在这种情况下,我通过 Socket.io 发送通知,因此完成速度非常快。

    至于检测该通知的取消,正如其他人所提到的,当beforeunload 事件触发时,创建一个像let didEnterBeforeUnload = false 这样的全局变量可以设置为true。在此之后,通过创建第三个事件,就像这样(同样,在 TypeScript 中),您可以推断用户按下取消

    window.addEventListener('focus', (e) => {
    
      if (didEnterBeforeUnload) {
        console.log('pressed cancel')
      }
    
      didEnterBeforeUnload = false
    });
    

    不过,作为旁注,这些事件不会 (iirc) 触发,除非您与页面进行了交互。因此,在测试期间尝试离开之前,请务必点击或点击该页面。

    我希望这对其他人有帮助!

    【讨论】:

    • 检测是否按下取消按钮的解决方法对我有用。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多