Есть ли кросс-браузер onload событие при нажатии кнопки Назад?
для всех основных браузеров (кроме IE), JavaScript onload событие не срабатывает при загрузке страницы в результате операции кнопки "назад" - оно срабатывает только при первой загрузке страницы.
может ли кто-нибудь указать мне на какой-то пример кросс-браузерного кода (Firefox, Opera, Safari, IE,...), который решает эту проблему? Я знаком с Firefox pageshow событие, но, к сожалению, ни Opera, ни Safari не реализуют это.
15 ответов:
Ребята, я обнаружил, что jQuery имеет только один эффект: страница перезагружается при нажатии кнопки "Назад". Это не имеет никакого отношения к "готов".
как это работает? Ну, JQuery добавляет onunload прослушивателя событий.
// http://code.jquery.com/jquery-latest.js jQuery(window).bind("unload", function() { // ...по умолчанию он ничего не делает. Но каким-то образом это, похоже, вызывает перезагрузку в Safari, Opera и Mozilla-независимо от того, что содержит обработчик событий.
[изменить(Николай): вот почему это работает именно так: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://stackoverflow.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://stackoverflow.com">click me, then press the back button</a> </body>
некоторые современные браузеры (Firefox, Safari и Opera, но не Chrome) поддерживают специальный кэш "назад/вперед" (я назову его bfcache, который является термином, изобретенным Mozilla), задействованный при переходе пользователя назад. В отличие от обычного (HTTP) кэша, он захватывает полное состояние страницы (включая состояние JS, DOM). Это позволяет ему повторно загрузить страницу быстрее и точно так же, как пользователь оставил его.
на
loadсобытие не должно срабатывать, когда страница загружается из этого bfcache. Например, если вы создали свой пользовательский интерфейс в обработчике "load", и событие "load" было запущено один раз при начальной загрузке, а во второй раз, когда страница была повторно загружена из bfcache, страница будет иметь повторяющиеся элементы пользовательского интерфейса.именно поэтому добавление обработчика "выгрузка" останавливает сохранение страницы в bfcache (что замедляет переход обратно) -- обработчик выгрузки может выполнять задачи очистки, которые могут оставить страницу в нерабочем состоянии государство.
для страниц, которые должны знать, когда они перемещаются прочь / назад, Firefox 1.5+ и версия Safari с исправлением для ошибка 28758 поддержка специальных мероприятий под названием "pageshow"и " pagehide".
ссылки:
я столкнулся с проблемой, что мой js не выполнялся, когда пользователь нажал назад или вперед. Сначала я решил остановить браузер от кэширования, но это, похоже, не проблема. Мой javascript был настроен на выполнение после всех библиотек и т. д. были заряжены. Я проверил их с помощью события readyStateChange.
после некоторого тестирования я обнаружил, что readyState элемента на странице, где был нажат back, не "загружен", а "завершен". Добавление
|| element.readyState == 'complete'к моему условное высказывание решило мои проблемы.просто подумал, что я поделюсь своими выводами, надеюсь, они помогут кому-то еще.
изменить для полноты
мой код выглядит следующим образом:
script.onreadystatechange(function(){ if(script.readyState == 'loaded' || script.readyState == 'complete') { // call code to execute here. } });в примере кода выше переменной скрипта был вновь созданный элемент скрипта, который был добавлен в DOM.
хорошо, вот окончательное решение, основанное на первоначальном решении ckramer и примере palehorse, который работает во всех браузерах, включая Opera. Если вы установите историю.navigationMode до "совместимого", тогда функция готовности jQuery будет срабатывать при операциях с кнопкой "Назад" в Opera, а также в других основных браузерах.
этой странице дополнительная информация.
пример:
history.navigationMode = 'compatible'; $(document).ready(function(){ alert('test'); });Я тестировал это в Opera 9.5, IE7, FF3 и Safari, и это работает во всех из них.
Я не мог заставить приведенные выше примеры работать. Я просто хотел вызвать обновление определенных измененных областей div при возвращении на страницу с помощью кнопки "Назад". Трюк, который я использовал, состоял в том, чтобы установить скрытое поле ввода (называемое "грязным битом") на 1, Как только области div изменились от оригинала. Скрытое поле ввода фактически сохраняет свое значение, когда я нажимаю назад, поэтому onload я могу проверить этот бит. Если он установлен, Я обновляю страницу (или просто обновляю divs). На первоначальной нагрузке, однако, бит не установлен, поэтому я не трачу время на загрузку страницы дважды.
<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>и он будет срабатывать правильно всякий раз, когда я нажал кнопку Назад.
Если я правильно помню, то добавление события unload () означает, что страница не может быть кэширована (в прямом/обратном кэше) - потому что это изменения состояния/может измениться, когда пользователь переходит прочь. Таким образом, небезопасно восстанавливать состояние последней секунды страницы при возврате к ней путем навигации по объекту истории.
Я думал, что это будет для "onunload", а не для загрузки страницы, так как мы не говорим о запуске события при ударе"назад"? $документ.ready () предназначен для событий, необходимых при загрузке страницы, независимо от того, как вы попадаете на эту страницу (т. е. перенаправление, открытие браузера на URL-адрес напрямую и т. д.), а не при нажатии "назад", если вы не говорите о том, что стрелять на предыдущей странице, когда он загружается снова. И я не уверен, что страница не кэшируется, поскольку я обнаружил, что Javascripts все еще есть, даже когда $документ.ready() входит в их состав. Мы должны были нажать Ctrl+F5 при редактировании наших сценариев, которые имеют это событие, когда мы их пересматриваем, и мы хотим проверить результаты на наших страницах.
$(window).unload(function(){ alert('do unload stuff here'); });это то, что вы хотите для события onunload при нажатии "назад" и выгрузке текущей страницы, а также будет срабатывать, когда пользователь закрывает окно браузера. Это звучало больше похоже на то, что было желательно, даже если я превосходил численностью $document.живой отклик. В основном разница между событие, запускаемое на текущей странице во время ее закрытия или на той, которая загружается при нажатии кнопки "назад" во время загрузки. Протестировано в IE 7 отлично, не могу говорить за другие браузеры, поскольку они не разрешены там, где мы находимся. Но это может быть другой вариант.
Я могу подтвердить 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>
для людей, которые не хотят использовать всю библиотеку jquery я извлек реализацию в отдельном коде. Это всего лишь 0,4 КБ.
вы можете найти код вместе с немецким учебником в этой Вики: http://www.easy-coding.de/wiki/html-ajax-und-co/onload-event-cross-browser-kompatibler-domcontentloaded.html
Билл, я осмелюсь ответить на ваш вопрос, однако я не уверен на 100% с моими догадками. Я думаю, что другие браузеры IE при переходе пользователя на страницу в истории не только загрузят страницу и ее ресурсы из кэша, но и восстановят для нее все состояние DOM (read session). IE не выполняет восстановление DOM (или при аренде не делал), и поэтому событие onload выглядит необходимым для правильной повторной инициализации страницы.
Я попробовал решение от Билла с помощью $(документ).готовый... но сначала это не сработало. Я обнаружил, что если скрипт помещается после раздела html, он не будет работать. Если это головной раздел, он будет работать, но только в IE. Скрипт не работает в Firefox.
хорошо, я попробовал это, и он работает в 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>
выгрузить событие не работает нормально на IE 9. Я попробовал его с load event (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>
я использовал шаблон html. В обычае этого шаблона.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
Comments