检测用户是否离开网页的最佳方法是什么?
onunload JavaScript事件并不是每次都有效(HTTP请求所花费的时间比终止浏览器所需的时间长)。
创建一个可能会被当前的浏览器阻止。
检测用户是否离开网页的最佳方法是什么?
onunload JavaScript事件并不是每次都有效(HTTP请求所花费的时间比终止浏览器所需的时间长)。
创建一个可能会被当前的浏览器阻止。
一种(略显笨拙的)方法是用AJAX调用服务器端来替换和链接,指示用户离开,然后使用相同的javascript块将用户带到他们所请求的外部站点。
当然,如果用户只是关闭浏览器窗口或输入新的URL,这是行不通的。
为了解决这个问题,您可能需要在页面上使用Javascript的setTimeout(),每隔几秒钟进行一次AJAX调用(取决于您想要知道用户是否已经离开的速度)。
尝试onbeforeunload事件:它在页面卸载之前被触发。它还允许你询问用户是否真的想要离开。参见onbeforeunload演示。
或者,您可以在他离开时发送Ajax请求。
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
});
我知道这个问题已经被回答了,但如果你只想在实际浏览器关闭时触发一些东西,而不仅仅是在页面加载发生时,你可以使用以下代码:
window.onbeforeunload = function (e) {
if ((window.event.clientY < 0)) {
//window.localStorage.clear();
//alert("Y coords: " + window.event.clientY)
}
};
在我的例子中,我正在清除本地存储并用鼠标y坐标提醒用户,只有当浏览器关闭时,这将在程序内的所有页面加载中被忽略。
这里有一个替代的解决方案-因为在大多数浏览器的导航控件(导航栏,选项卡等)位于页面内容区域的上方,你可以检测到鼠标指针通过顶部离开页面,并显示一个“离开前”对话框。它完全不引人注目,它允许你在用户实际执行离开操作之前与他们进行交互。
$(document).bind("mouseleave", function(e) {
if (e.pageY - $(window).scrollTop() <= 1) {
$('#BeforeYouLeaveDiv').show();
}
});
缺点是,这当然是一种猜测,用户真的想要离开,但在绝大多数情况下,这是正确的。
为了它的价值,这是我所做的,也许它可以帮助其他人,即使文章是旧的。
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个人不会同时注册为一个用户。
可能不是最有效的解决方案,但它确实有效。
多亏了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事件将不会给异步代码运行时间。在异步的情况下,我发现能见度变化和mouseleave事件是最好的选择。当用户更改选项卡、隐藏浏览器或将courser移出窗口作用域时,这些事件将触发。
文档。addEventListener (mouseleave, e = > { //执行一些异步代码 }) 文档。addEventListener (visibilitychange, e = > { 如果文档。visbilitystate === 'visible') { //报告用户处于焦点中 }其他{ //报告用户不聚焦 } })
页面可见性API
✅页面可见性API提供了可以观察的事件,以了解文档何时变得可见或隐藏。
✅当用户最小化窗口或切换到另一个选项卡时,API触发可见性变化事件。
✅我们可以根据visibilityState执行操作
function onVisibilityChange() {
if (document.visibilityState === 'visible') {
console.log("user is focused on the page")
} else {
console.log("user left the page")
}
}
document.addEventListener('visibilitychange', onVisibilityChange);