Атрибут onunload тега <body>
Описание
Атрибут onunload позволяет задать JavaScript-код, который выполняется при выгрузке страницы (закрытии вкладки/окна или переходе на другую страницу). Однако его использование имеет важные ограничения и особенности.
Важно: Современные браузеры ограничивают работу onunload в целях производительности и безопасности. Не полагайтесь на него для критически важных операций.
Пример использования (с оговорками):
<body onunload="cleanupBeforeUnload()">
<script>
function cleanupBeforeUnload() {
// Отправка аналитики о времени на странице
const timeSpent = Date.now() - pageLoadTime;
navigator.sendBeacon('/analytics', `time=${timeSpent}`);
// Закрытие соединений
if (socket) socket.close();
}
const pageLoadTime = Date.now();
let socket; // Пример соединения
</script>
</body>
Ключевые ограничения:
| Браузер | Ограничения |
|---|---|
| Chrome | Строгие таймауты, асинхронные операции могут не завершиться |
| Firefox | Более лоялен, но также имеет ограничения |
| Safari | Сильно ограничивает выполнение кода |
| Мобильные | Часто вообще не срабатывает |
Рекомендации по использованию:
- Используйте только для не критических операций
- Для аналитики применяйте
navigator.sendBeacon() - Избегайте сложных вычислений и DOM-операций
- Сохраняйте важные данные сразу при изменении
- Тестируйте поведение во всех целевых браузерах
Современные альтернативы:
<script>
// 1. Page Visibility API (рекомендуется)
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
// Страница стала невидимой (возможно скоро выгрузится)
navigator.sendBeacon('/save-data', lastData);
}
});
// 2. beforeunload (более надежен чем unload)
window.addEventListener('beforeunload', () => {
// Только синхронные операции
localStorage.setItem('autosave', JSON.stringify(data));
});
// 3. Периодическое автосохранение
setInterval(() => {
saveToServer();
}, 30000); // Каждые 30 секунд
</script>
Что нельзя делать в onunload:
- Показывать диалоговые окна (alert/confirm)
- Выполнять длительные операции (более 500мс)
- Делать сложные AJAX-запросы (используйте sendBeacon)
- Пытаться отменить переход/закрытие
- Полагаться на выполнение кода в мобильных браузерах
Практический пример с sendBeacon:
window.addEventListener('unload', function() {
// Корректный способ отправки аналитики
const analytics = {
page: window.location.pathname,
timeSpent: Date.now() - performance.timing.navigationStart,
events: trackedEvents
};
const blob = new Blob([JSON.stringify(analytics)], {type: 'application/json'});
navigator.sendBeacon('/analytics', blob);
// Простые синхронные операции
localStorage.setItem('last_activity', new Date().toISOString());
});
Статистика надежности:
- Chrome: ~70% случаев срабатывает корректно
- Firefox: ~85% случаев
- Safari: ~50% случаев
- Mobile Safari: менее 30% случаев
- Android Browser: ~40% случаев
Примечание: Для критически важных операций (сохранение данных, завершение сеанса) используйте комбинацию Page Visibility API, периодического автосохранения и обработки beforeunload. Не полагайтесь только на onunload.