Safari后退按钮问题

时间:2008-08-23 06:43:08

标签: javascript safari

我为当地社区大学做一些小编程和网络工作。这项工作包括维护一个非常庞大且灵魂破坏的网站,其中包括VBScript,javascript,Dreamweaver产生的混乱和一系列附加组件,各种各样的conmen已经说服他们多年来购买。

几天前,我接到一个电话“网站正在锁定使用Safari的人!”好的,第一步下载Safari(v3.1.2),第二步冲浪到网站。一切似乎都很好。

长话短说我终于解决了这个问题,它与Safari的后退按钮有关。该网站使用了一个花式裤子javascript菜单,可以在我尝试过的每个浏览器中使用,包括Safari,这是第一次。但是在Safari中,如果您按下页面上的链接然后点击后退按钮,则菜单不再有效。

我做了一个简化的网页来说明原理。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com">Coding Horror</a>
</body>
</html>

加载页面,您会看到警告框。然后按照页面上的链接点击后退按钮。在IE和Firefox中,您再次看到警报框,在Safari中您没有。

经过一次激烈的谷歌搜索后,我发现其他人有类似的问题,但没有真正令人满意的答案。所以我的问题是,在用户点击后退按钮之后,如何让我的页面在Safari中以相同的方式工作,就像在其他浏览器中一样?

如果这是一个愚蠢的问题,请保持温和,javascript对我来说有点新鲜。

11 个答案:

答案 0 :(得分:18)

Stefan的iframe解决方案有效,但如果不够优雅,我发现以下JavaScript也解决了这个问题:

window.onunload = function(){};

也就是说,如果您的菜单是JavaScript,那么您可能更愿意使用JavaScript解决此问题。

卸载事件处理程序定义的想法来自这篇Firefox 1.5文章:https://developer.mozilla.org/en/Using_Firefox_1.5_caching

答案 1 :(得分:9)

将它放在body标签中 <body onunload="">

每次点击后退按钮

时,这将强制执行safari,chrome,FF重新加载

答案 2 :(得分:8)

这是Mobile Safari的一个很好的解决方案:

/*! Reloads page on every visit */
function Reload() {
    try {
        var headElement = document.getElementsByTagName("head")[0];
        if (headElement && headElement.innerHTML)
            headElement.innerHTML += " ";
        } catch (e) {}
    }

    /*! Reloads on every visit in mobile safari */
    if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
        window.onpageshow = function(evt) {
            if (evt.persisted) {
                document.body.style.display = "none";
                location.reload();
            }
        };
    }

source

我根据自己的需要对其进行了修改,但现在还可以。 (如果你不修改它,请刷新烦人的白色屏幕。)

答案 3 :(得分:8)

请不要遵循任何告诉您忽略缓存的建议。页面缓存有一个原因 - 改善用户体验。您使用的方法会让用户体验变得更糟,所以除非您讨厌您的用户,否则请不要这样做。

Safari(桌面和iOS)的正确解决方案是使用pageshow事件而不是onload事件(请参阅https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching了解这些事件)。

pageshow事件将在您希望触发onload事件的同时触发,但在通过缓存提供网页时也会起作用。无论如何,这似乎都是你想要的。

答案 4 :(得分:7)

iframe解决了这个问题:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head><title>Safari Back Button Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body onload="alert('Hello');">
<a href="http://www.codinghorror.com">Coding Horror</a>
<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
this prevents back forward cache
</iframe>
</body>
</html>

更多details

答案 5 :(得分:3)

我不知道导致问题的是什么,但我知道谁可以帮到你。 Safari建立在Webkit之上,缺少Apple(不是那么社区意识),Webkit team可能知道问题所在。

这根本不是一个愚蠢的问题。

答案 6 :(得分:3)

我注意到一些非常相似的东西。我认为这是因为Firefox和IE在返回时会再次从服务器检索页面而Safari则不会。您是否尝试过添加页面到期/无缓存标头?当我发现这种行为但我还没有时间的时候,我会调查它。

答案 7 :(得分:3)

$(window).bind("pageshow", function(event) {
  if (event.originalEvent.persisted) {
    window.location.reload() 
  }
});

here最近回复mshah

答案 8 :(得分:1)

我知道这个帖子已经有一年了,但我刚刚使用ProjectSeven的Safari backbutton修复程序修复了一个完全相同的Safari问题。像魅力一样。

http://www.projectseven.com/extensions/info/safaribbfix/index.htm

答案 9 :(得分:0)

在iPad上遇到同样的问题。

不是很漂亮,但它有效:)。它是如何工作的。

我意识到在iPad Safari上,按下后退按钮时没有重新加载页面。我每秒在页面上放一个计数器,然后保存当前的时间戳。

加载页面时,计数器和时间会同步。在后退按钮上,计数器在停止的位置继续,并且时间戳和计数器之间存在间隙。如果间隙大于500毫秒,则强制重新加载页面。

在文件action.js

var showLoadingBoxSetIntervalVar;
var showLoadingBoxCount = 0;
var showLoadingBoxLoadedTimestamp = 0

function showLoadingBox(text) {

    var showLoadingBoxSetIntervalVar=self.setInterval(function(){showLoadingBoxIpadRelaod()},1000);
    showLoadingBoxCount = 0
    showLoadingBoxLoadedTimestamp = new Date().getTime();

    //Here load the spinner

}

function showLoadingBoxIpadRelaod()
{
    //Calculate difference between now and page loaded time minus threshold 500ms
    var diffTime = ( (new Date().getTime()) - showLoadingBoxLoadedTimestamp - 500)/1000;

    showLoadingBoxCount = showLoadingBoxCount + 1;
    var isiPad = navigator.userAgent.match(/iPad/i) != null;

    if(diffTime > showLoadingBoxCount && isiPad){
        location.reload();
    }
}

答案 10 :(得分:0)

尝试一下
if(performance.navigation.type == 2){
alert(“ Hello”);
}