Після повернення в історію Firefox JavaScript не працюватиме


84

Коли я використовую кнопку назад у Firefox, щоб перейти на раніше відвідану сторінку, скрипти на цій сторінці не запускатимуться знову .

Є там якісь виправлення / обхідні шляхи для повторного запуску сценаріїв під час перегляду сторінки вдруге?

Зверніть увагу, що я протестував ті самі сторінки в Google Chrome та Internet Explorer, і вони працюють за призначенням.


Ось файли та кроки, які я використовував для перевірки проблеми:

(перейдіть до 0.html, натисніть, щоб перейти до 1.html, кнопка назад)

0.html

<html><body>
<script>
  window.onload = function() { alert('window.onload alert'); };
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>

1.html

<html><body>
<p>Go BACK!</p>
</body></html>

Відповіді:


92

Встановіть порожню функцію, яку потрібно викликати у window.onunload:

window.onunload = function(){}; 

напр

<html><body>
<script type="text/javascript">
  window.onload = function() { alert('window.onload alert'); };
  window.onunload = function(){};
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>

Джерело: http://www.firefoxanswer.com/firefox/672-firefoxanswer.html (архівна версія)


2
Дякую, це працює. Будь-який натяк на те, що робить обробник за замовчуванням onunload? (наприклад, я перевизначаю тут якусь поведінку за замовчуванням?)
Патонца

Добре, дякую, я розслідую. Ще раз спасибі, ця проблема переслідує мене вже деякий час :)
Патонца

хтось знає, навіщо це потрібно FireFox, а іншим браузерам - ні?
Пім Ягер

7
Ви нічого не перевизначаєте, це просто заважає Firefox кешувати сторінку в кеші зворотного пересилання (bfcache). developer.mozilla.org/en/DOM/window.onunload developer.mozilla.org/En/Using_Firefox_1.5_caching
Кріс Хаас

1
Незважаючи на те, що він повинен зламати bfcache, на жаль, здається, він все ще пам'ятає попередню сторінку - зокрема, якщо завантажені URL-адреси iframe завантажуються знову, коли ви повертаєтеся назад, і якщо згенерований вміст потрібно було помістити у фрейм, там, схоже, немає перехресного браузера спосіб оновити це заново.
NoBugs

76

Коли я використовую кнопку "Назад" у Firefox, щоб перейти на попередньо відвідану сторінку, сценарії на цій сторінці не запускатимуться знову.

Це правильно, і це добре.

Коли ви натискаєте посилання у Firefox (і Safari, і Opera), це не відразу знищує вашу сторінку, щоб перейти до наступної. Він зберігає сторінку цілою, просто приховуючи її від очей. Якщо натиснути кнопку "Назад", вона поверне стару сторінку до перегляду, не завантажуючи документ знову; це набагато швидше, що призводить до плавніших переходів сторінки вперед / назад для користувача.

Ця функція називається bfcache .

Будь-який вміст, який ви додали на сторінку під час попереднього завантаження користувача та використання його, все одно буде там. Будь-які обробники подій, які ви прикріпили до елементів сторінки, все одно будуть прикріплені. Будь-які встановлені вами тайм-аути / інтервали все ще будуть активними. Тож рідко буває будь-яка причина, по якій вам потрібно знати, що вас сховали та показали знову. Було б неправильно onloadповторно викликати або вбудовувати код сценарію, тому що будь-яке прив'язування та генерація вмісту, яку ви зробили в цій функції, буде виконуватися вдруге над тим самим вмістом, що може мати катастрофічні результати. (наприклад,document.write вбудований скрипт повністю знищить сторінку.)

Причиною того, що письмо до window.onunloadмає ефект, є те, що браузери, що реалізують bfcache, вирішили, що - для сумісності зі сторінками, які дійсно повинні знати, коли їх відкидають - будь-яка сторінка, яка заявляє про зацікавленість знати, колиonunload це відбудеться, спричинить bfcache бути інвалідом. Ця сторінка буде завантажена свіжою, коли ви повернетесь до неї, а не завантажені з bfcache.

Отже, якщо ви встановите window.onunload= function() {};, те, що ви насправді робите, навмисно порушує bfcache. Це призведе до того, що ваші сторінки повільно орієнтуються, і їх не слід використовувати, крім як крайній захід.

Якщо вам потрібно знати, коли користувач залишає або повертається на вашу сторінку, не псуючи bfcache, ви можете замість цього захопити події onpageshowта onpagehide:

window.onload=window.onpageshow= function() {
    alert('Hello!');
};

3
Моя проблема полягає в тому, що bfcache не кешує ВСЮ сторінку, тому мені потрібно повторно запустити js, щоб відновити втрачений вміст. Тож розбиття цілої сторінки може бути нормальним. У будь-якому випадку, я не використовую подію window.onload, я використовую подію jQuery document.ready. Чи знаєте ви спосіб, як і раніше мати можливість використовувати document.ready та уникнути цієї проблеми?
Патонца

bfcache взагалі повинен повертати всю сторінку такою, якою вона була, коли вона була залишена. Якого вмісту не вистачає після повернення з попередньої сторінки? (тестовий приклад?) document.readyпрацюватиме по суті так само, як і window.onload(для деяких браузерів вони і так є однаковою подією).
bobince

14
Це НЕ добре, оскільки він не запускає javascript знову, враховуючи, що він кешований ... але насправді НЕ кешує зміни, внесені раніше javascript. Якщо javascript зникає в елементі під час завантаження сторінки, він не зникає знову, коли відвідуєш історію ... але ЗАПОЧАЄ його знову з непрозорістю 0, скасовуючи те, що зробив javascript! Це має бути ВСЕ АБО НІЩО. Ви повинні кешувати повний стан сторінки після запуску javascript, якщо ви хочете представити його кешованим, не запускаючи javascript знову!
Джимбо Джонні,

1
@Jimbo: Будь ласка, тест-кейс. bfcache призначений (і у кожному випадку, який я коли-небудь бачив, і зберігає) зберігати точний стан DOM над приховуванням / показуванням. Елемент, який був вицвілим, залишатиметься непрозорим після повернення сторінки, якщо тільки інший сценарій не буде запущений, щоб знову його приховати.
bobince

1
@bobince - Створіть елемент із файлом CSS, встановивши непрозорість на нуль, а потім використовуйте деякі jQuery, щоб він зникав у готовому документі. Повернувшись в історію, він повторно застосує таблицю стилів CSS (нуль), не зберігаючи непрозорість: 1, яку JS додав до атрибуту style, коли його затухає. При першому відвідуванні сторінки елемент буде зникати з нуля до 1. Перейдіть на іншу сторінку і натисніть у відповідь, і вона буде просто сидіти там повністю прозорою.
Джимбо Джонні

23

Ви можете перевірити persistedвластивість pageshowподії. При початковому завантаженні сторінки встановлюється значення false. Коли сторінка завантажується з кешу, для неї встановлюється значення true.

window.onpageshow = function(event) {
    if (event.persisted) {
        alert("From bfcache");
    }
};

З якоїсь причини jQuery не має цієї властивості у випадку. Ви можете знайти його за оригінальною подією.

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        alert("From bfcache");
    }
});

Дякуємо, що надали як версії javascript, так і jquery! Ви там пропустили тісну дужку в кінці (це не стогін!). Також заради інших я зазначу, що звіт про IE та Chrome .persisted завжди є хибним, незалежно від цього.
Магнус Сміт

Як зазначав Магнус, це не працювало для мене в Chrome, доки я не видалив оператор if.
Джастін

Це працювало для мене в Chrome 58.0.3029.110 (64-розрядна версія) та FF 53.0.2 (64-розрядна версія) без будь-яких змін.
kmoser

1

Підключення до події "onunload", яка нічого не робить:

<html><body>
<script type="text/javascript">
  window.onload = function() { alert('window.onload alert'); };
  window.onunload = function(){}; 
  alert('inline alert');
</script>
<a href="1.html">Click Me!</a>
</body></html>

Не впевнений, я віддав голос "за", схоже, хтось просто проголосував за кожну відповідь на це питання ...
Patonza

до своєї відповіді слід додати, що додавання події onunload на вашу сторінку фактично вимкне кешування сторінки в цілому. Це не просто змушує JS запускатись знову, це також змушує навантаження на сервер зростати вгору. Це насправді не пропозиція сприймати легковажно, це слід ретельно продумати.
dreagan

@dreagan, це вимикає bfcache, але не обов'язково кеш HTTP. Кеш-пам’ять HTTP має цілий інший набір правил. Якщо ви кидаєте там серверний режим сну, ви повинні це помітити під час натискання назад. Про це Mozilla розповідає у своєму третьому питанні щодо поширених запитань щодо BFCache .
Кріс Хаас,

Я говорив про BFcache, мав це вказати. Це не означає, що ви повинні подавати такі пропозиції, не повідомляючи ОП про наслідки. Альтернативою може бути використання події onpopstate, щоб спробувати знову запустити javascript.
дріган

Я досі не знаю, чи розумію. Чому "завантаження сервера зростає на ступінь", якщо локальний bfcache клієнта обходить? Так, DOM потрібно буде перебудувати, але HTML повинен бути частиною кешу HTTP клієнта. Так, потрібно буде перезавантажити додаткові ресурси, але вони також повинні бути частиною кешу HTTP клієнта. Що стосується onpopstate, коли це питання було задано майже п’ять років тому, ця подія була ще відносно новою, а підтримка браузера була дуже непослідовною
Кріс Хаас,

1

Наскільки я знаю, Firefox не запускає onLoadподію ззаду.

Натомість він повинен запускати onFocus на основі цього посилання тут .


Тестували це, і windows.onfocus дійсно викликає, навіть не встановлюючи порожній обробник window.onunload. Налаштування onunload є трохи приємнішим обхідним шляхом, але .onfocus теж повинен бути нормальним. Дякую :)
Патонца

1

Простим способом змусити сторінку виконувати JavaScript, коли користувач повертається до неї за допомогою історії браузера, є подія OnPopState. Ми використовуємо це для паузи та відтворення відео на нашій домашній сторінці ( https://fynydd.com ).

window.onpopstate = function() {

    // Do stuff here...
};

0

для деяких випадків, таких як операції ajax, можна використовувати прослуховувач зміни URL-адреси

$(window).on('hashchange', function() {
        ....
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.