2010-01-18 5 views
4

Ce problème semble se produire uniquement dans la dernière version de Safari (4.0.4). En utilisant l'exemple ci-dessous, la page créera une boîte d'alerte après 60 minutes. Si vous ouvrez la page suivante, cliquez sur le lien vers Google, et appuyez sur le bouton de retour de votre navigateur, rien ne se passera. Cela fonctionne comme prévu.Comportement de setTimeout inattendu dans Safari 4.0.4

Cependant, si j'ouvre la page suivante dans Safari, cliquez sur le lien, puis appuyez sur le bouton de retour, la boîte d'alerte apparaîtra immédiatement. Cela semble se produire seulement au premier essai et ne se produira pas jusqu'à ce que je fasse un rafraichissement ou ferme complètement Safari.

Est-ce prévu?

<!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> 

Répondre

4

Bon point! Confirmé.

Cela a à voir avec le cache du bouton précédent/suivant. Lorsque vous quittez la page dans Firefox ou Safari (mais pas Chrome), l'ancienne page est toujours chargée, juste cachée. Si vous cliquez sur «retour», il peut alors afficher à nouveau la page sans avoir à la ré-analyser et relancer tout le JavaScript, ce qui rendra la navigation plus rapide (particulièrement utile pour les pages qui commencent à chercher du contenu via AJAX).

Dans Firefox, le délai d'expiration d'un délai est conservé, donc si vous avez cinq secondes avant le délai, quittez la page, attendez trois secondes et revenez, le délai expirera dans deux secondes supplémentaires. Si le délai d'attente s'est déclenché alors que vous étiez loin de la page, il se déclenchera immédiatement lorsque vous reviendrez. Safari semble actuellement tirer tous les délai d'expiration restant sur le retour à la page, au lieu de seulement ceux qui ont été programmés pour tirer dans le passé. À mon avis, c'est un bug. Voulez-vous le signaler, ou dois-je?

Vous pouvez contourner ce problème en faisant en sorte que la fonction de temporisation vérifie l'heure réelle via new Date().getTime() avant de passer à l'action. Cela est parfois utile pour certains types de timeout, car le temps de rappel peut dériver vers l'arrière en raison de l'occupation du navigateur ou de la dissimulation de la page dans bfcache. Mais en raison de ce bug, il peut maintenant aller de l'avant aussi. Malheureusement, il semble que Safari n'implémente pas la fonction onpagehide que Firefox a introduite pour aller avec le bfcache, donc vous ne pouvez pas l'attraper.

Une autre option serait de naviguer dans sniff pour Safari et, une fois trouvée, désactiver la bfcache en définissant une fonction window.onunload - même une qui ne fait rien. Firefox et Safari prennent ceci comme un signal que la page veut être vraiment déchargée en partant.

+0

Cette erreur semble se produire uniquement lors de l'exécution à partir d'un site non-ssl. Je peux reproduire le problème en visitant la page http: //localhost/test.html. Cependant, le bug n'apparaît pas lorsque je visite https: //localhost/test.html. – nivlam

+0

Oui, je crois que Firefox et Safari désactivent le bfcache sur les pages HTTPS. – bobince

Questions connexes