[英]Best way to detect when a user leaves a web page?
檢測用戶是否離開網頁的最佳方法是什么?
onunload
JavaScript 事件並非每次都起作用(HTTP 請求花費的時間比終止瀏覽器所需的時間長)。
創建一個可能會被當前的瀏覽器阻止。
嘗試onbeforeunload
事件:它在頁面卸載之前觸發。 它還允許您詢問用戶是否真的想離開。 請參閱演示onbeforeunload Demo 。
或者,您可以在他離開時發送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) {
}
在頁面卸載之前將其觸發。
如果您需要執行一些異步代碼(例如向服務器發送一條消息,表明用戶現在沒有關注您的頁面),則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 } })
感謝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')
)
}
})
我知道這個問題已經得到解答,但如果您只想在實際 BROWSER 關閉時觸發某些東西,而不僅僅是在頁面加載發生時,您可以使用以下代碼:
window.onbeforeunload = function (e) {
if ((window.event.clientY < 0)) {
//window.localStorage.clear();
//alert("Y coords: " + window.event.clientY)
}
};
在我的示例中,我正在清除本地存儲並使用鼠標 y 坐標提醒用戶,僅當瀏覽器關閉時,這將在程序內的所有頁面加載中被忽略。
一種(有點笨拙)的方法是使用 AJAX 調用到服務器端來替換和鏈接離開您的站點的鏈接,指示用戶正在離開,然后使用相同的 javascript 塊將用戶帶到他們的外部站點已要求。
當然,如果用戶只是關閉瀏覽器窗口或輸入新的 URL,這將不起作用。
為了解決這個問題,您可能需要在頁面上使用 Javascript 的 setTimeout(),每隔幾秒進行一次 AJAX 調用(取決於您想知道用戶是否離開的速度)。
您可以做的是在頁面加載時打開WebSocket連接,可選擇通過標識當前用戶的 WebSocket 發送數據,並檢查該連接何時在服務器上關閉。
對於它的價值,這就是我所做的,即使文章很舊,它也可能對其他人有所幫助。
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);
對 activeUser.php 的 Ajax 調用
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 個用戶。
可能不是最有效的解決方案,但它可以完成工作。
頁面可見性 API
✅ Page Visibility API 提供了可以觀察的事件,以了解文檔何時可見或隱藏。
✅當用戶最小化窗口或切換到另一個選項卡時,API 會觸發visibilitychange
事件。
✅我們可以根據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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.