簡體   English   中英

檢測用戶何時離開網頁的最佳方法?

[英]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事件不會給異步代碼運行時間。 在異步的情況下,我發現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 } })

感謝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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM