Атрибут 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.