2010-01-18 2 views
4

Такое поведение наблюдается только в последней версии Safari (4.0.4). Используя приведенный ниже пример, страница создаст окно оповещения через 60 минут. Если вы откроете следующую страницу, нажмите ссылку на Google и нажмите кнопку возврата своего браузера, ничего не произойдет. Это работает так, как ожидалось.Неожиданное поведение setTimeout в Safari 4.0.4

Однако, если я открою следующую страницу в Safari, перейдите по ссылке, затем нажмите кнопку «Назад», появится окно предупреждения. Кажется, это происходит только с первой попытки и не повторится, пока я не сделаю жесткое обновление или полностью закрываю Safari.

Ожидается ли это?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 

<head> 
    <script type="text/javascript"> 
     window.onload = function() { 
       setTimeout(function() { 
        alert('hit'); 
       }, 60 * 60 * 1000); 
     } 
    </script> 
</head> 

<body> 
    <a href="http://www.google.com">Click me, then press the browser's back button.</a> 
</body> 

</html> 

ответ

4

Хорошее место! Подтверждено.

Это связано с кешем задней/передней кнопки. Когда вы покидаете страницу в Firefox или Safari (но не в Chrome), она сохраняет старую страницу еще загруженной, просто скрытой. Если вы нажмете «назад», он может повторно показать страницу без повторного анализа и повторного запуска всего JavaScript, что приведет к гораздо более быстрой навигации (особенно полезно для страниц, запускающих загрузку через AJAX onload).

В Firefox время таймаута будет срабатывать, поэтому, если у вас есть пять секунд, чтобы пройти до таймаута, оставьте страницу, подождите три секунды и вернитесь, тайм-аут будет срабатывать еще две секунды. Если тайм-аут был бы запущен, пока вы были вдали от страницы, он сразу же срабатывает, когда вы вернетесь. В настоящее время Safari запускает каждые оставшийся тайм-аут при возврате на страницу, а не только те, которые планировались в прошлом. По-моему, это ошибка. Хотите сообщить об этом, или я должен?

Вы можете обойти это, выполнив функцию тайм-аута в реальном времени через new Date().getTime(), прежде чем предпринимать действия. Это иногда полезно для некоторых видов тайм-аутов в любом случае, так как время обратного вызова может отклоняться назад из-за того, что браузер занят или страница скрыта от bfcache. Но из-за этой ошибки он теперь может двигаться вперед. К сожалению, похоже, Safari также не реализует функцию onpagehide, введенную Firefox для работы с bfcache, поэтому вы не можете ее поймать.

Другим вариантом является браузер-sniff для Safari и, если обнаружено, отключить bfcache, установив функцию window.onunload - даже тот, который ничего не делает. Firefox и Safari воспринимают это как сигнал о том, что страница хочет быть действительно выгруженной при выходе.

+0

Эта ошибка возникает только при работе с сайтом, отличным от ssl. Я могу воспроизвести проблему при посещении страницы http: //localhost/test.html. Однако ошибка появляется, когда я посещаю https: //localhost/test.html. – nivlam

+0

Да, я считаю, что Firefox и Safari отключили bfcache на HTTPS-страницах. – bobince

Смежные вопросы