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

2020/10/17 17:41 · javascript ·  · 0评论

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

onunloadJavaScript事件不起作用每次(HTTP请求花费的时间比需要的时间终止浏览器)。

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

尝试以下onbeforeunload事件:在页面卸载前将其触发。它还允许您询问用户是否真的要离开。参见演示onbeforeunload演示

另外,您可以在他离开时发出Ajax请求。

Mozilla开发人员网络对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
});

这是另一种解决方案-由于在大多数浏览器中,导航控件(导航栏,标签等)都位于页面内容区域上方,因此您可以检测到鼠标指针从顶部离开页面并在显示“离开之前”对话。它完全不引人注目它使您可以在用户实际执行要离开的操作之前与其进行交互

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

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

我知道已经回答了这个问题,但是如果您只希望在关闭实际的BROWSER时(而不只是在发生页面加载时)触发某些内容,则可以使用以下代码:

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

在我的示例中,我正在清除本地存储并用鼠标y坐标警告用户,仅当关闭浏览器时,在程序中所有页面加载时都将忽略此操作。

一种做到这一点的方法(有点hacky)是替换并通过AJAX调用将链接从您的站点引向服务器端,指示用户正在离开,然后使用相同的javascript块将用户带到他们所访问的外部站点已经要求。

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

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

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

// 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')
    )
  }
})

在您需要执行一些异步代码的情况下(例如向服务器发送一条消息,表明用户现在不在您的页面上),该事件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
    }  
})

对于它的价值,这就是我所做的,即使这篇文章比较陈旧,它也可以帮助其他人。

PHP:

session_start();

$_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR'];

if(isset($_SESSION['userID'])){
    if(!strpos($_SESSION['activeID'], '-')){
        $_SESSION['activeID'] = $_SESSION['userID'].'-'.$_SESSION['activeID'];
    }
}elseif(!isset($_SESSION['activeID'])){
    $_SESSION['activeID'] = time();
}

JS

window.setInterval(function(){
            var userid = '<?php echo $_SESSION['activeID']; ?>';
            var ipaddress = '<?php echo $_SESSION['ipaddress']; ?>';
            var action = 'data';

            $.ajax({
                url:'activeUser.php',
                method:'POST',
                data:{action:action,userid:userid,ipaddress:ipaddress},
                success:function(response){
                     //alert(response);                 
                }
            });
          }, 5000);

Ajax调用activeUser.php

if(isset($_POST['action'])){
    if(isset($_POST['userid'])){
        $stamp = time();
        $activeid = $_POST['userid'];
        $ip = $_POST['ipaddress'];

        $query = "SELECT stamp FROM activeusers WHERE activeid = '".$activeid."' LIMIT 1";
        $results = RUNSIMPLEDB($query);

        if($results->num_rows > 0){
            $query = "UPDATE activeusers SET stamp = '$stamp' WHERE activeid = '".$activeid."' AND ip = '$ip' LIMIT 1";
            RUNSIMPLEDB($query);
        }else{
            $query = "INSERT INTO activeusers (activeid,stamp,ip)
                    VALUES ('".$activeid."','$stamp','$ip')";
            RUNSIMPLEDB($query);
        }
    }
}

数据库:

CREATE TABLE `activeusers` (
  `id` int(11) NOT NULL,
  `activeid` varchar(20) NOT NULL,
  `stamp` int(11) NOT NULL,
  `ip` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

基本上每5秒js就会发布到一个php文件,该文件将跟踪用户和用户的IP地址。活动用户只是数据库记录,该记录在5秒钟内更新了数据库时间戳。老用户停止更新到数据库。ip地址仅用于确保用户唯一,因此该站点上的2个用户不能同时注册为1个用户。

可能不是最有效的解决方案,但可以完成任务。

本文地址:http://javascript.askforanswer.com/jianceyonghuheshilikaiwangyedezuijiafangfa.html
文章标签:
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!