Как прослушать закрытие страницы или действие обновления

внешний интерфейс Android Ajax Открытый исходный код

оригинал:Как отслеживать закрытие или обновление страницы

По сути, эту статью можно назвать и тем, как отслеживать и загружать продолжительность видео, которое смотрит пользователь. В последнее время возникла необходимость отслеживать действие пользователя по воспроизведению видео и сообщать о событии воспроизведения.Что необходимо сообщать, так это продолжительность просмотра пользователем видео. Здесь может быть несколько ситуаций. Одна из них заключается в том, что пользователь нажимает для воспроизведения, а затем запускается событие video.ended до тех пор, пока видео не будет воспроизведено, и в это время сообщается время просмотра пользователем, что легче обрабатывать. Второй случай - пользователь покидает или обновляет страницу после нажатия кнопки play. О событии нужно сообщить до того, как пользователь уйдет. Здесь в основном срабатывает событие window.onunload. Кажется, что это можно сделать, но на самом деле есть подводные камни.

Поскольку техническое решение, принятое компанией, — .m3u8 (hls), и этот формат в настоящее время поддерживается только Safari в браузерах ПК, а большинство других браузеров, таких как chrome, Firefox или мобильный Android, не поддерживают этот формат. Таким образом, решение с использованием собственного тега видео недостаточно, и вам нужно найти какие-то плагины или проигрыватели. В конце концов я выбрал DPlayer, относительно неплохой проигрыватель с открытым исходным кодом, который прост в использовании. Серьезно, сообщите, сколько времени пользователь смотрел видео.

Важное обновление

После инструкции @音客 в области комментариев используйтеNavigator.sendBeacon()Он будет лучше поддерживать отчеты о событиях. Это API, предназначенный для обработки скрытых точек данных, но, пожалуйста, обратите внимание на проблемы совместимости браузера при его использовании. В настоящее время (2018.06) поддерживается мобильный терминал Android 5 или выше, а также iOS версии 11.3 или выше. выше требуется.CanIUse. В этой статье используетсяnew Image()метод может бытьsendBeacon()Метод обработки перехода на более раннюю версию, когда он несовместим, для получения дополнительной информации см.:Используйте navigator.sendBeacon() для передачи данных.

Цель

Время просмотра сообщается, когда пользователь заканчивает просмотр видео.

Готов к работе

    const dp = new DPlayer({
        container: document.getElementById('dplayer'),
        screenshot: true,
        video: {
            url: 'xx.m3u8',
            pic: 'xx.jpg',
            type: 'customHls',
            customType: {
                'customHls': function (video, player) {
                    const hls = new Hls();
                    hls.loadSource(video.src);
                    hls.attachMedia(video);
                }
            }
        }
    });

    // 是否播放的标记
    var isPlay = false;
    dp.on('play', function () {
        console.log('player start');
        isPlay = true;
    });

В первом общем случае пользователь полностью закончил просмотр видео.

    dp.on('ended', function () {
      console.log('player ended');
      sendVideoPlayEvent(); //上报事件方法
      isPlay = false;
    });

Во втором случае закройте браузер или обновите страницу

Запускается, когда пользователь закрывает страницу или обновляет браузерonunloadсобытие пользователь начинает смотреть видео и покидает страницу, и этот период времени является продолжительностью просмотра видео пользователем.

    window.onunload = function () {
      sendVideoPlayEvent();
      isPlay = false;
      console.log('onunload');
    };

яма

После тестирования обнаружено, что при отправке VideoPlayEvent, если используется ajax, будь то post или get, он будет недействительным. Причина здесь может заключаться в том, что страница закрывается слишком быстро для выполнения ajax. Проверив множество решений, я, наконец, обнаружил, что это событие нужно инициировать с помощью хитрого метода. Он заключается в использовании атрибута src тега img для инициирования запроса на получение ресурсов при вставке img в тело, и сервер может обработать этот маршрут Наконец, обнаружено, что этот метод выполним, и о событии успешно сообщается. при выгрузке. .

    function sendVideoPlayEvent() {
      if (isPlay) {
        var videoId = getQueryString('videoId');
        var duration = dp.video.currentTime; // 视频播放时间可以直接通过currentTime获得
        var img = new Image();
        img.style.display = 'none';
        img.src = `/api/video/play?duration=${duration}&videoId=${videoId}`; // 服务端处理接口
        document.body.appendChild(img);
      }
    }
    function getQueryString(name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]); return null;
    }

Суммировать

  1. Подумав об этом, src тега script также должен быть реализован, но я не проверял это.
  2. Ям всегда много, больше включай мозги. . .
  3. Идея немного ограничена, должны быть другие решения, предложения приветствуются.