Есть ли кросс-браузер onload событие при нажатии кнопки Назад?



для всех основных браузеров (кроме IE), JavaScript onload событие не срабатывает при загрузке страницы в результате операции кнопки "назад" - оно срабатывает только при первой загрузке страницы.



может ли кто-нибудь указать мне на какой-то пример кросс-браузерного кода (Firefox, Opera, Safari, IE,...), который решает эту проблему? Я знаком с Firefox pageshow событие, но, к сожалению, ни Opera, ни Safari не реализуют это.

402   15  

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

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

Билл, я осмелюсь ответить на ваш вопрос, однако я не уверен на 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

    Ничего не найдено.