Лучший способ определить, когда пользователь покидает веб-страницу?

Каков наилучший способ определить, покидает ли пользователь веб-страницу?

Событие JavaScript onunload не работает каждый раз (HTTP-запрос занимает больше времени, чем требуется для завершения работы браузера).

Создание одного из них, вероятно, будет заблокировано текущими браузерами.

Ответ 1

Попробуйте событие onbeforeunload: оно запускается непосредственно перед выгрузкой страницы. Это также позволяет вам спросить, действительно ли пользователь хочет уйти. Смотрите демонстрацию onbeforeunload Demo.

В качестве альтернативы вы можете отправить запрос Ajax, когда он уйдет.

Ответ 2

У 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
});

Ответ 3

Для этого я использую:

window.onbeforeunload = function (e) {

}

Он запускается непосредственно перед выгрузкой страницы.

Ответ 4

Здесь альтернативное решение - поскольку в большинстве браузеров элементы навигации (панель навигации, вкладки и т.д.) расположены над областью содержимого страницы, вы можете обнаружить указатель мыши, оставляя страницу сверху, и отображать "до вы покидаете" диалог. Он абсолютно ненавязчив и позволяет вам взаимодействовать с пользователем до того, как они действительно выполнит действие, которое нужно оставить.

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

Недостатком является то, что, конечно, это предположение, что пользователь действительно собирается уйти, но в подавляющем большинстве случаев это правильно.

Ответ 5

Я знаю, что на этот вопрос был дан ответ, но если вы хотите только что-то вызвать, когда фактический BROWSER будет закрыт, а не только при возникновении pageload, вы можете использовать этот код:

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

В моем примере я очищаю локальное хранилище и предупреждаю пользователя с помощью мышей y coords, только когда браузер закрыт, это будет игнорироваться при всех загрузках страниц из программы.

Ответ 6

Один (слегка взломанный) способ сделать это - это замена и ссылки, которые приводят вас в сторону от вашего сайта с вызовом AJAX на стороне сервера, указывая, что пользователь уходит, а затем использовать тот же блок javascript, чтобы заставить пользователя которые он запросил.

Конечно, это не сработает, если пользователь просто закрывает окно браузера или создает новый URL-адрес.

Чтобы обойти это, вам может потребоваться использовать Javascript setTimeout() на странице, делая вызов AJAX каждые несколько секунд (в зависимости от того, как быстро вы хотите узнать, ушел ли пользователь).

Ответ 7

Для чего это стоит, это то, что я сделал, и, возможно, это может помочь другим, даже если статья старая.

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 пользователь.

Вероятно, не самое эффективное решение, но оно делает свою работу.

Ответ 8

Благодаря специалистам по обслуживанию можно реализовать решение, подобное Адаму, исключительно на стороне клиента, если браузер его поддерживает. Просто обойти запросы сердцебиения:

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