检测用户何时离开网页的最佳方法?

时间:2008-09-29 05:30:46

标签: javascript

检测用户是否离开网页的最佳方法是什么?

onunload JavaScript事件每次都不起作用(HTTP请求的时间比终止浏览器所需的时间长)。

当前浏览器可能会阻止创建一个。

9 个答案:

答案 0 :(得分:208)

尝试onbeforeunload事件:在卸载页面之前触发它。它还允许您回询用户是否真的要离开。请参阅演示 onbeforeunload Demo

或者,您可以在他离开时发出Ajax请求。

答案 1 :(得分:14)

Mozilla Developer Network有一个很好的描述和onbeforeunload的例子。

如果您想在离开页面之前警告用户,如果您的页面很脏(例如,如果用户输入了一些数据):

window.addEventListener('beforeunload', function(e) {
  var myPageIsDirty = ...; //you implement this logic...
  if(myPageIsDirty) {
    //following two lines will cause the browser to ask the user if they
    //want to leave. The text of this dialog is controlled by the browser.
    e.preventDefault(); //per the standard
    e.returnValue = ''; //required for Chrome
  }
  //else: user is allowed to leave without a warning dialog
});

答案 2 :(得分:10)

为此我正在使用:

window.onbeforeunload = function (e) {

}

在卸载页面之前触发它。

答案 3 :(得分:5)

这是一个替代解决方案 - 因为在大多数浏览器中导航控件(导航栏,标签等)位于上面页面内容区域,您可以检测鼠标指针通过顶部离开页面并在离开前显示" "对话。它完全不引人注意它允许您在实际执行要离开的操作之前与用户进行交互。

$(document).bind("mouseleave", function(e) {
    if (e.pageY - $(window).scrollTop() <= 1) {    
        $('#BeforeYouLeaveDiv').show();
    }
});

缺点是当然用户实际打算离开猜测,但在绝大多数情况下它是正确的。

答案 4 :(得分:4)

我知道这个问题已经得到解答,但是如果您只想在实际的BROWSER关闭时触发某些内容,而不仅仅是在发生页面加载时,您可以使用以下代码:

window.onbeforeunload = function (e) {
        if ((window.event.clientY < 0)) {
            //window.localStorage.clear();
            //alert("Y coords: " + window.event.clientY)
        }
};

在我的示例中,我正在清除本地存储并使用mouses y coords向用户发出警报,只有在浏览器关闭时,才会在程序中的所有页面加载中忽略这一点。

答案 5 :(得分:3)

一种(略微hacky)方式是替换和链接从您的站点通过AJAX调用到服务器端,指示用户正在离开,然后使用相同的JavaScript块将用户带到他们要求的外部网站。

当然,如果用户只是关闭浏览器窗口或输入新的URL,这将无效。

要解决这个问题,您可能需要在页面上使用Javascript的setTimeout(),每隔几秒钟进行一次AJAX调用(取决于您想知道用户离开的速度)。

答案 6 :(得分:2)

感谢Service Workers,只要浏览器支持,就可以完全在客户端上实现类似于Adam's的解决方案。只是规避心跳请求:

// The delay should be longer than the heartbeat by a significant enough amount that there won't be false positives
const liveTimeoutDelay = 10000
let liveTimeout = null

global.self.addEventListener('fetch', event => {
  clearTimeout(liveTimeout)
  liveTimeout = setTimeout(() => {
    console.log('User left page')
    // handle page leave
  }, liveTimeoutDelay)
  // Forward any events except for hearbeat events
  if (event.request.url.endsWith('/heartbeat')) {
    event.respondWith(
      new global.Response('Still here')
    )
  }
})

答案 7 :(得分:2)

在您需要执行一些异步代码的情况下(例如向服务器发送一条消息,表明用户当前不在您的页面上),事件beforeunload将不会给异步代码运行时间。对于异步情况,我发现visibilitychangemouseleave事件是最好的选择。当用户更改选项卡,隐藏浏览器或将课程向导移出窗口范围时,将触发这些事件。

document.addEventListener('mouseleave', e=>{
     //do some async code
})

document.addEventListener('visibilitychange', e=>{
     if (document.visibilityState === 'visible') {
   //report that user is in focus
    } else {
     //report that user is out of focus
    }  
})

答案 8 :(得分:0)

您可以做的是,在页面加载时打开一个 WebSocket 连接,可以选择通过标识当前用户的 WebSocket 发送数据,并检查该连接何时在服务器上关闭。