Safari 4.0.4中出现意外的setTimeout行为

时间:2010-01-18 16:33:54

标签: javascript safari

此行为似乎只发生在最新版本的Safari(4.0.4)中。使用下面的示例,该页面将在60分钟后创建一个警告框。如果您打开以下页面,请单击指向Google的链接,然后点击浏览器的后退按钮,不会发生任何事情。这按预期工作。

但是,如果我在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>

1 个答案:

答案 0 :(得分:4)

好地方!确认。

与后退/前进按钮缓存有关。当您将页面保留在Firefox或Safari(但不是Chrome)中时,它会保持旧页面仍然加载,只是隐藏。如果你点击“返回”,它就可以重新显示页面而无需重新解析它并重新运行所有JavaScript,从而导致更快的导航(对于通过AJAX onload开始获取内容的页面尤其有用)。 / p>

在Firefox中,将保留超时将触发的时间,因此如果您在超时之前有五秒钟的时间,请离开页面,等待三秒钟然后再返回,超时将在两秒内触发。如果在您离开页面时超时会被触发,那么当您回来时它会立即触发。 Safari目前似乎在返回页面时触发每个剩余的超时,而不仅仅是那些计划在过去触发的超时。在我看来这是一个错误。想报告,还是我?

您可以通过让超时功能在执行操作之前通过new Date().getTime()检查实时来解决此问题。这对于某些类型的超时有时是有用的,因为回调时间可能由于浏览器繁忙或页面被bfcache隐藏而向后漂移。但由于这个错误,它现在也可以向前移动。不幸的是,似乎Safari也没有实现Firefox引入的onpagehide函数与bfcache一起使用,所以你无法捕捉到它。

另一种选择是对Safari进行浏览器嗅探,并在找到时通过设置window.onunload函数来禁用bfcache - 即使是什么都不做。 Firefox和Safari将此视为该页面在离开时真正卸载的信号。