首页 文章

Safari后退按钮问题

提问于
浏览
42

我为当地社区大学做一些小编程和网络工作 . 这包括保持一个非常大和灵魂破坏网站,包括VBScript中,JavaScript的一个杂牌波奇的工作,Dreamweaver生成的冗余代码和各种赌侠大战说服他们买多年来的附加组件的集合 .

几天前,我接到一个电话“网站正在锁定使用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对我来说有点新鲜 .

10 回答

  • 2

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

    window.onunload = function(){};
    

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

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

  • 3

    把它放在身体标签 <body onunload="">

    每次点击“返回”按钮时,这将强制执行safari,chrome,FF重新加载

  • 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

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

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

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

  • 1

    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

  • 0

    我不知道是什么导致了这个问题,但我知道谁可以帮到你 . Safari Build 在Webkit之上,缺少Apple(不是那么社区意识)Webkit team可能知道问题是什么 .

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

  • 7

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

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

    最近通过mshah回答here .

  • 9

    我知道这个帖子已经有一年了,但我只是使用ProjectSeven的Safari backbutton修复程序修复了一个完全相同的Safari问题 . 奇迹般有效 .

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

  • 8

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

相关问题