Javascript Safari后退按钮问题

Javascript Safari后退按钮问题,javascript,safari,Javascript,Safari,我在当地一所社区学院做一些次要的编程和网络工作。这项工作包括维护一个非常庞大、破坏灵魂的网站,该网站由VBScript、javascript、Dreamweaver生成的cruft和一系列附加组件组成,多年来,各种骗子说服他们购买这些附加组件 几天前,我接到一个电话,“网站正在为使用Safari的人锁定!”好的,第一步下载Safari(v3.1.2),第二步浏览网站。一切似乎都很好 长话短说,我终于发现了这个问题,它与Safari的后退按钮有关。该网站使用了一个花哨的javascript菜单,在

我在当地一所社区学院做一些次要的编程和网络工作。这项工作包括维护一个非常庞大、破坏灵魂的网站,该网站由VBScript、javascript、Dreamweaver生成的cruft和一系列附加组件组成,多年来,各种骗子说服他们购买这些附加组件

几天前,我接到一个电话,“网站正在为使用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>

Safari后退按钮测试
加载页面,您将看到警报框。然后按照页面上的链接点击后退按钮。在IE和Firefox中,您会再次看到警报框,而在Safari中则不会

在谷歌搜索之后,我发现其他人也有类似的问题,但没有真正令人满意的答案。因此,我的问题是,在用户点击后退按钮后,如何使我的页面在Safari中以与在其他浏览器中相同的方式工作


如果这是一个愚蠢的问题,请温和一点,javascript对我来说有点陌生。

我不知道是什么导致了问题,但我知道谁可以帮助你。Safari是建立在苹果的基础上的,而苹果(没有那么多社区意识)可能知道问题所在


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

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

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>

Safari后退按钮测试
这会阻止前向缓存

更多

Stefan的iframe解决方案可行,但如果这还不够优雅,我发现以下JavaScript也能解决这个问题:

window.onunload = function(){};
也就是说,如果您的菜单是JavaScript,那么您可能更愿意使用JavaScript来解决这个问题


卸载事件处理程序定义的想法来自Firefox 1.5文章:。

我知道这个线程已经有一年了,但我刚刚使用ProjectSeven的Safari backbutton修复修复了一个相同的Safari only问题。工作起来很有魅力

只要把这个放在body标签上就行了


这将迫使safari、chrome、FF在每次按下“后退”按钮时重新加载。这是一个很好的移动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();
            }
        };
    }
()


我根据自己的需要修改了它,但按原样是可以的。(如果不修改,刷新时会出现恼人的白色屏幕)。

在iPad上也有同样的问题

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

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

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

在文件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();
    }
}

请不要按照任何建议忽略缓存。缓存页面的原因是为了改善用户体验。你使用的方法会让用户体验更糟,所以除非你讨厌你的用户,否则不要这样做

Safari(桌面和iOS)的正确解决方案是使用
pageshow
事件,而不是
onload
事件(请参阅了解它们是什么)

pageshow
事件将在您希望触发
onload
事件的同时触发,但当页面通过缓存提供服务时,该事件也会起作用。这似乎是你想要的

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

最近的回答是。

试试这个 如果(performance.navigation.type==2){
警报(“你好”);

}

这很有趣,因为ProjectSeven是我刚才提到的javascript菜单。最终放弃了它,改成了自制的jquery。从body标签中的onload移动到jquery的document.ready为我解决了这个问题;您可以找到。尽管我使用的是jQuery的$(document).ready事件,但Safari中的“后退”按钮仍有问题。我添加了上面的代码,它解决了这个问题。看起来这个问答仍然是相关的。当考虑到浏览器的怪癖时,人们倾向于只考虑IE,但“其他人”(Webkit、Firefox)也有它们,尽管这些怪癖更轻微、更难以捉摸……@Mika Tuupola:Safari不仅在iOS上可用。我不认为操作系统在Safari的行为中起到任何作用,你也必须有一个更新版本的Safari。我没有任何iOS设备,所以耸耸肩。@LeeKowalkowski操作系统确实对它有影响-Safari for iOS不起作用,而OS X版本确实起作用@杰西:那他们显然是不同的野兽!我想我会删除这个答案。我真的无法帮助那些一开始使用
onload
事件就看不到问题的人(提示:这不是一个伟大的事件,也可能不是你认为的那样,即:触发太晚了)嘿,Auto,你知道这一点了吗?我已经在iPad和iPod上尝试了下面的所有解决方案,但当客户端按下后退按钮时,我无法让Safari运行JavaScript。(当我在桌面上试用Safari时,我可以得到它,但我不能让它在Safari的移动版本上工作。这是你曾经使用过的东西吗?)检查问题的答案onload()事件在Safari中没有触发,当点击后退按钮时Sal我最终找到了答案。我在中使用jquery的“document.ready”调用了我的函数