Answers:
尝试以下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();
}
});
不利的一面是,当然是用户实际上打算离开的猜测,但是在大多数情况下,这是正确的。
为此,我正在使用:
window.onbeforeunload = function (e) {
}
在页面卸载之前将其触发。
onbeforeunload
?
我知道已经回答了这个问题,但是如果您只希望在关闭实际的BROWSER时(而不只是在发生页面加载时)触发某些内容,则可以使用以下代码:
window.onbeforeunload = function (e) {
if ((window.event.clientY < 0)) {
//window.localStorage.clear();
//alert("Y coords: " + window.event.clientY)
}
};
在我的示例中,我正在清除本地存储并用鼠标y坐标警告用户,仅当关闭浏览器时,在程序中所有页面加载时都将忽略此操作。
e
在这种情况下为变量): stackoverflow.com/questions/9813445/ …
This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user.
developer.mozilla.org/en-US/docs/Web/API/Window/event
一种实现方式(略为骇客)是替换和链接,这些链接通过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')
)
}
})
setInterval(() => fetch('/heartbeat'), 5000)
吗?
在您需要执行一些异步代码的情况下(例如向服务器发送一条消息,表明用户当前不在您的页面上),该事件beforeunload
不会给异步代码运行时间。在异步情况下,我发现visibilitychange
和mouseleave
事件是最好的选择。当用户更改选项卡,隐藏浏览器或将课程表移出窗口范围时,将触发这些事件。
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个用户。
可能不是最有效的解决方案,但可以完成工作。