При нажатии кнопки "Назад" происходит событие кросс-браузерной загрузки?

Для всех основных браузеров (кроме 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

Готовое событие jQuery было создано именно для такого рода проблем. Возможно, вы захотите покопаться в реализации, чтобы увидеть, что происходит под одеялом.

Я попробовал решение от Билла, используя $(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();
}
Другие вопросы по тегам