При нажатии кнопки "Назад" происходит событие кросс-браузерной загрузки?
Для всех основных браузеров (кроме IE), JavaScript onload
Событие не запускается, когда страница загружается в результате действия кнопки "Назад" - оно запускается только при первой загрузке страницы.
Может кто-нибудь указать мне пример кросс-браузерного кода (Firefox, Opera, Safari, IE,...), который решает эту проблему? Я знаком с Firefox pageshow
событие, но, к сожалению, ни Opera, ни Safari не реализуют это.
16 ответов
Ребята, я обнаружил, что JQuery имеет только один эффект: страница перезагружается при нажатии кнопки назад. Это не имеет ничего общего с " готовым ".
Как это работает? Ну, JQuery добавляет прослушиватель событий onunload.
// http://code.jquery.com/jquery-latest.js
jQuery(window).bind("unload", function() { // ...
По умолчанию это ничего не делает. Но почему-то это вызывает перезагрузку в Safari, Opera и Mozilla - независимо от того, что содержит обработчик событий.
[ edit (Николай): вот почему это работает так: webkit.org, developer.mozilla.org. Пожалуйста, прочитайте эти статьи (или мое резюме в отдельном ответе ниже) и подумайте, действительно ли вам нужно это сделать и замедлить загрузку вашей страницы для пользователей.]
Не можете в это поверить? Попробуй это:
<body onunload=""><!-- This does the trick -->
<script type="text/javascript">
alert('first load / reload');
window.onload = function(){alert('onload')};
</script>
<a href="http://stackru.com">click me, then press the back button</a>
</body>
Вы увидите аналогичные результаты при использовании JQuery.
Вы можете сравнить с этим без onunload
<body><!-- Will not reload on back button -->
<script type="text/javascript">
alert('first load / reload');
window.onload = function(){alert('onload')};
</script>
<a href="http://stackru.com">click me, then press the back button</a>
</body>
Некоторые современные браузеры (Firefox, Safari и Opera, но не Chrome) поддерживают специальный кэш "назад / вперед" (я назову его "bfcache" - термин, придуманный Mozilla), используемый при переходе пользователя назад. В отличие от обычного (HTTP) кэша, он фиксирует полное состояние страницы (включая состояние JS, DOM). Это позволяет перезагружать страницу быстрее и в точности так, как ее покинул пользователь.
load
событие не должно запускаться, когда страница загружается из этого bfcache. Например, если вы создали свой пользовательский интерфейс в обработчике "load", а событие "load" было запущено один раз при начальной загрузке и во второй раз, когда страница была перезагружена из bfcache, страница закончила бы с дубликаты элементов интерфейса.
По этой же причине добавление обработчика "unload" останавливает сохранение страницы в bfcache (что замедляет переход к ней) - обработчик unload может выполнять задачи очистки, которые могут привести страницу в нерабочее состояние.
Для страниц, которые должны знать, когда они перемещаются назад или обратно, Firefox 1.5+ и версия Safari с исправлением для ошибки 28758 поддерживают специальные события, называемые "pageshow" и "pagehide".
Рекомендации:
Я столкнулся с проблемой, что мой js не выполнялся, когда пользователь нажимал назад или вперед. Сначала я решил остановить кеширование браузера, но, похоже, это не проблема. Мой javascript был настроен на выполнение после загрузки всех библиотек и т. Д. Я проверил это с помощью события readyStateChange.
После некоторого тестирования я обнаружил, что readyState элемента на странице, где был нажат назад, не "загружен", а "завершен". Добавление || element.readyState == 'complete'
чтобы мое условное заявление решило мои проблемы.
Просто подумал, что поделюсь своими выводами, надеюсь, они помогут кому-то еще.
Изменить для полноты
Мой код выглядел следующим образом:
script.onreadystatechange(function(){
if(script.readyState == 'loaded' || script.readyState == 'complete') {
// call code to execute here.
}
});
В приведенном выше примере кода переменной сценария был недавно созданный элемент сценария, который был добавлен в DOM.
Хорошо, вот окончательное решение, основанное на первоначальном решении ckramer и примере Palehorse, которое работает во всех браузерах, включая Opera. Если вы установили history.navigationMode в "совместимый", тогда функция готовности jQuery будет срабатывать при операциях с кнопками "Назад" в Opera, а также в других основных браузерах.
Эта страница имеет больше информации.
Пример:
history.navigationMode = 'compatible';
$(document).ready(function(){
alert('test');
});
Я проверял это в Opera 9.5, IE7, FF3 и Safari, и он работает во всех из них.
Я не мог заставить приведенные выше примеры работать. Я просто хотел вызвать обновление определенных модифицированных областей div при возврате на страницу с помощью кнопки "Назад". Уловка, которую я использовал, состояла в том, чтобы установить скрытое поле ввода (называемое "грязный бит") в 1, как только области div изменились от оригинала. Скрытое поле ввода на самом деле сохраняет свое значение, когда я нажимаю назад, поэтому при загрузке я могу проверить этот бит. Если он установлен, я обновляю страницу (или просто обновляю div). Однако при первоначальной загрузке этот бит не установлен, поэтому я не трачу время на загрузку страницы дважды.
<input type='hidden' id='dirty'>
<script>
$(document).ready(function() {
if ($('#dirty').val()) {
// ... reload the page or specific divs only
}
// when something modifies a div that needs to be refreshed, set dirty=1
$('#dirty').val('1');
});
</script>
И он будет срабатывать правильно, когда я нажму кнопку "Назад".
Я могу подтвердить ckramer, что готовое событие jQuery работает в IE и FireFox. Вот пример:
<html>
<head>
<title>Test Page</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var d = new Date();
$('#test').html( "Hi at " + d.toString() );
});
</script>
</head>
<body>
<div id="test"></div>
<div>
<a href="http://www.google.com">Go!</a>
</div>
</body>
</html>
Я думал, что это будет для "onunload", а не для загрузки страницы, так как мы не говорим о запуске события при нажатии "Назад"? $document.ready() - для событий, желаемых при загрузке страницы, независимо от того, как вы попадаете на эту страницу (например, перенаправление, открытие браузера по URL-адресу напрямую и т. д.), а не при нажатии "Назад", если вы не говорите о том, что выстрелить на предыдущей странице, когда он загружается снова. И я не уверен, что страница не кэшируется, так как я обнаружил, что Javascripts все еще есть, даже если в них включен $ document.ready (). Нам приходилось нажимать Ctrl+F5 при редактировании наших сценариев, которые имеют это событие, всякий раз, когда мы их пересматриваем, и мы хотим проверить результаты на наших страницах.
$(window).unload(function(){ alert('do unload stuff here'); });
это то, что вы хотели бы для события onunload при нажатии "Назад" и выгрузке текущей страницы, а также срабатывает, когда пользователь закрывает окно браузера. Это больше походило на то, что вы хотели, даже если меня превосходят ответы $ document.ready (). В основном, разница между событием, запускаемым на текущей странице во время ее закрытия, и тем, которое загружается при нажатии "Назад" во время загрузки. Протестировано в IE 7 хорошо, не могу говорить за другие браузеры, так как они не разрешены, где мы находимся. Но это может быть другой вариант.
Если я правильно помню, то добавление события unload() означает, что страница не может быть кэширована (в прямом / обратном кэше) - потому что ее состояние изменяется / может измениться, когда пользователь уходит. Так что - небезопасно восстанавливать состояние последней секунды страницы при возврате к ней путем навигации по объекту истории.
Для людей, которые не хотят использовать всю библиотеку jquery, я извлек реализацию в отдельный код. Это всего 0,4 КБ.
Вы можете найти код вместе с учебником немецкого языка в этой вики: http://web.archive.org/web/20130417092220/http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html
Я попробовал решение от Билла, используя $(document).ready... но сначала это не сработало. Я обнаружил, что если скрипт размещен после раздела html, он не будет работать. Если это головной раздел, он будет работать, но только в IE. Скрипт не работает в Firefox.
Билл, я смею ответить на твой вопрос, однако я не уверен на 100% в своих догадках. Я думаю, что другие браузеры IE при переносе пользователя на страницу в истории не только загрузят страницу и ее ресурсы из кэша, но и восстановят для нее все состояние DOM (чтение сеанса). IE не выполняет восстановление DOM (или не сдавал в аренду), и, таким образом, событие onload представляется необходимым для правильной повторной инициализации страницы.
Хорошо, я попробовал это, и это работает в Firefox 3, Safari 3.1.1 и IE7, но не в Opera 9.52.
Если вы используете приведенный ниже пример (на основе примера palehorse), вы получите всплывающее окно с предупреждением при первой загрузке страницы. Но если вы затем перейдете на другой URL, а затем нажмете кнопку "Назад", чтобы вернуться на эту страницу, вы не получите всплывающее окно с предупреждением в Opera (но вы делаете это в других браузерах).
Во всяком случае, я думаю, что это достаточно близко на данный момент. Спасибо всем!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled Document</title>
<meta http-equiv="expires" content="0">
<script src="jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(
function(){
alert('test');
}
);
</script>
</head>
<body>
<h1>Test of the page load event and the Back button using jQuery</h1>
</body>
</html>
Я использовал HTML-шаблон. В файле custom.js этого шаблона была такая функция:
jQuery(document).ready(function($) {
$(window).on('load', function() {
//...
});
});
Но эта функция не работала, когда я возвращался после перехода на другую страницу.
Итак, я попробовал это, и это сработало:
jQuery(document).ready(function($) {
//...
});
//Window Load Start
window.addEventListener('load', function() {
jQuery(document).ready(function($) {
//...
});
});
Теперь у меня есть 2 "готовых" функции, но они не дают никаких ошибок, и страница работает очень хорошо.
Тем не менее, я должен заявить, что он тестировал на Windows 10 - Opera v53 и Edge v42, но не на других браузерах. Имейте в виду это...
Примечание: версия jquery была 3.3.1, а версия перехода была 3.0.0
Событие unload не работает нормально в IE 9. Я пробовал его с событием load (onload()), оно отлично работает в IE 9 и FF5.
Пример:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
jQuery(window).bind("load", function() {
$("[name=customerName]").val('');
});
</script>
</head>
<body>
<h1>body.jsp</h1>
<form action="success.jsp">
<div id="myDiv">
Your Full Name: <input name="yourName" id="fullName"
value="Your Full Name" /><br> <br> <input type="submit"><br>
</div>
</form>
</body>
</html>
Я создаю веб-сайт на основе протокола file:///. (Firefox 116.0.1 64bit). Так что это может не относиться ко многим ситуациям здесь:
Но когда я использовал кнопку «Назад», чтобы перейти на страницу со сценариями, необходимыми для ее запуска, это не удалось. Щелкнуть ссылку на страницу не получится.
Определение неисправности: вкладка браузера блокируется, перестает отвечать на запросы и требует закрытия. Кнопки «Назад», «Вперед» и «Стоп» в браузере не были доступны для нажатия.
Когда я попробовалonunload=""
, последовала та же неудача...
Но когда я настроил реальную функцию для onunload И заставил ее вызвать функцию, которая была описана в атрибуте onload тега body, началась перезагрузка необходимого javasript.
Пример:
<body onload="page_defaults()" onunload="back_button_reload_fix()>
function back_button_reload_fix(){
page_defaults();
}