Цель
Мы хотим для определенного вида трафика попробовать при закрытии вкладки показывать человеку специальное предложение. Я знаю два способа дотянуться до человека когда он ушел.
- Ремаркетинг/ретаргетинг. То есть можно начать показывать специальный баннер такой аудитории на остальных сайтах по которым человек будет ходить.
- Повесить событие на закрытие страницы, которое заблокирует возможность выполнения этой операции.
С первым никаких вопросов нет, а вот со вторым все немного интереснее т.к. оказывается в разных браузерах поведение разное.
Исследование
Работу кода я проверял в текущих установленных у меня версиях браузеров:
- Google Chrome 55
- Mozilla Firefox 50.1
- Internet Explorer 11
body.unload
Я помнил из начала двухтысячных, что раньше можно было повесить событие на unload в body и чуть ли не иметь возможность не дать человеку вообще закрыть страницу просто возвращая false из обработчика. Поэтому посмотреть на поведение современных браузеров, переориентированных на людей, было очень интересно.
Обработчик unload пришлось навешивать через html-тег т.к. через jQuery-обработчик на это событие навесить у меня не получилось.
$('body').on('unload', function() {}); // не сработало
<body onunload="return vdmUnload();"> <!-- сработало -->
Выводы: событие обрабатывается, но что-либо предпринимать поздно. Вообще увидеть, что событие обрабатывается, получилось только благодаря сливанию в лог и галочкам "Preserve log". Это работает стабильно и правильно во всех браузерах, а вот с попыткой что-то показать все браузеры ведут себя по-разному:
Google Chrome
|
Mozilla Firefox
|
Internet Explorer
|
|
console.log
|
✓
|
✓
|
✓
|
$(div).show()
|
нет совсем
|
✓
|
только с alert/confirm
|
alert/confirm
|
нет совсем
ошибки в log
|
нет совсем
|
✓
|
return false
|
нет совсем
|
нет совсем
|
нет совсем
|
То есть в Google Chrome ничего не получилось сделать, чтобы показать что-то свое.
В Firefox не показывается alert/confirm, однако можно показать div и он показывается всегда, только очень быстро исчезает с экрана, да и то только в синтетическом случае с перезагрузкой страницы. Если же пользователь закрывает вкладку, а именно это наша цель, то никакой возможности показать что-то нет.
В IE самое странное поведение. С одной стороны он показывает alert/confirm. С другой стороны он не показывает div. Однако если совместить показ alert и div, то в этом случае код отработает так, как ожидалось и alert будет выведен поверх div.
Попытка внести искусственную задержку чтобы div был как можно дольше на экране в Firefox успехом не увеначалась.
window.onbeforeunload.
Это событие подавало больше надежд, т.к. оно срабатывает до закрытия страницы и на него вроде как можно повлиять, по крайней мере в документации говорится что оно "cancelable". На это событие можно повесить обработчик через jQuery.
Выводы: событие обрабатывается и поведение браузеров еще более разнообразное. Google Chrome блокирует любые действия обработчика и выполняет их только если человек согласится остаться на странице. Но хотя бы показывает диалог всегда. Mozilla Firefox не показывает диалог подтверждения закрытия если человек ничего не сделал на странице. За действие засчитывается клик в любой части страницы или кручение колесиком мышки. Оба браузера, не смотря на документацию, не выводят текст подтверждения закрытия. Делает это только IE.
Google Chrome
|
Mozilla Firefox
|
Internet Explorer
|
|
console.log
|
✓
|
✓
|
✓
|
$(div).show()
|
после диалога
|
✓
|
только с alert/confirm/текстом закрытия
|
alert/confirm
|
нет совсем
ошибки в лог
|
нет совсем
|
✓
|
возможность не дать закрыть страницу
|
✓
|
только если было взаимодействие
|
✓
|
свой текст закрытия
|
нет
стандартный диалог
|
нет
стандартный диалог
|
✓
|
Выводы
Нормально работающего решения для ситуации закрытия вкладки нет.
В Google Chrome вероятность очень маленькая. Максимум на что можно рассчитывать, что человек нажмет "Stay" в стандартном диалоге. Или начнет вбивать новый адрес в этой вкладке тогда мы "мигнем" ему нашим div и он может быть нажмет back или восстановит закрытую вкладку.
В Mozilla Firefox необходимо что-бы человек что-то сделал на странице. Ну "скроллом" он у нас воспользуется обязательно так что это не препятствие. Под стандартным диалогом он увидит наше сообщение. Нужно его только правильно спозиционировать на странице.
|
Mozilla Firefox
|
В Internet Explorer все работает максимально в соответствии с документацией. Можно вывести свое сообщение и показать что-то свое под диалогом. Правда диалог показывается посредине экрана, а не окна браузера.
|
Internet Explorer
|
Полезные ссылки и код
Полезные ссылки:
- https://developer.mozilla.org/en-US/docs/Web/Events/unload
- https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload
- http://www.w3schools.com/jsref/event_onunload.asp
- http://www.w3schools.com/jsref/event_onbeforeunload.asp
Код:
<!DOCTYPE html>
<html>
<head>
<style>
#dont-leave-us {width:80%; height: 142px; position: absolute; z-index:1; left: 10%; top:8%; background-color: purple; color: white; text-align: center; display: none; }
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
function _unload() {
console.log('body.unload')
$('#dont-leave-us').show().append('body.unload<br/>');
alert('alert will work only in IE');
confirm('confirm will work only in IE')
return false;
}
function _beforeunload(e) {
console.log('window.beforeunload')
$('#dont-leave-us').show().append('window.beforeunload<br/>');
var confirmationMessage = 'Text to show';
e.returnValue = confirmationMessage;
alert('alert will work only in IE');
confirm('confirm will work only in IE')
return confirmationMessage;
}
$(window).on('beforeunload', function(e) {
return _beforeunload(e);
});
</script>
<body _onunload="return _unload();">
<h1>Unload Test</h1>
<div id="dont-leave-us">
<h1>Don't Leave Us</h1>
</div>
</body>
</html>