簡體   English   中英

Safari 后退按鈕問題

[英]The Safari Back Button Problem

我為當地社區大學做一些小程序和網絡工作。 工作包括維護一個非常大的破壞靈魂的網站,該網站由一堆 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>

加載頁面,您會看到警報框。 然后點擊頁面上的鏈接並點擊后退按鈕。 在 IE 和 Firefox 中,您會再次看到警告框,而在 Safari 中則不會。

經過激烈的谷歌搜索,我發現其他人也有類似的問題,但沒有真正令人滿意的答案。 所以我的問題是,在用戶點擊后退按鈕后,如何讓我的頁面在 Safari 中以與在其他瀏覽器中相同的方式工作?

如果這是一個愚蠢的問題,請保持溫和,javascript 對我來說有點陌生。

Stefan 的 iframe 解決方案有效,但如果這還不夠優雅,我發現以下 JavaScript 也可以解決它:

window.onunload = function(){};

也就是說,如果您的菜單是 JavaScript,那么您可能更喜歡用 JavaScript 解決這個問題。

卸載事件處理程序定義的想法來自這篇 Firefox 1.5 文章: https : //developer.mozilla.org/en/Using_Firefox_1.5_caching

把它放在 body 標簽<body onunload="">

每次點擊返回按鈕時,這將強制 safari、chrome、FF 重新加載

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

來源

我根據我的需要修改了它,但它是可以的。 (如果您不修改它,刷新時會出現煩人的白屏)。

請不要遵循任何告訴您忽略緩存的建議。 頁面被緩存是有原因的——為了改善用戶體驗。 您使用的方法會使用戶體驗變得更糟,所以除非您討厭您的用戶,否則不要這樣做。

Safari(桌面和 iOS)的正確解決方案是使用pageshow事件而不是onload事件(有關這些事件的信息,請參閱https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching )。

pageshow事件將在您期望onload事件觸發的同時觸發,但當頁面通過緩存提供時它也將起作用。 無論如何,這似乎是您想要的。

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>

更多細節

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

最近由mshah 在這里回答。

我不知道是什么導致了問題,但我知道誰可以幫助你。 Safari 是建立在Webkit之上的,除了 Apple(他們沒有社區意識)之外, Webkit 團隊可能知道問題是什么。

這根本不是一個愚蠢的問題。

我注意到一些非常相似的事情。 我認為這是因為 Firefox 和 IE 在返回時再次從服務器檢索頁面,而 Safari 則沒有。 您是否嘗試過添加頁面到期/無緩存標頭? 當我發現這種行為時,我打算調查它,但還沒有時間。

我知道這個線程已經有一年了,但我只是使用 ProjectSeven 的 Safari 后退按鈕修復了一個相同的 Safari 唯一問題。 奇跡般有效。

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

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

嘗試這個
如果(性能。導航。類型== 2){
警報(“你好”);
}

在我的 Angular 應用程序中,我使用這個條件來解決這個問題。 首先,我在下面的index.html添加了onunload=""事件句柄

<body class="mat-typography" onunload="">
    <app-root></app-root>
</body>

然后在我的組件ngOnInit方法中,我添加了如下代碼

  public ngOnInit(): void {
    window.onpageshow = (event) => {
        if (event.persisted) {
            document.body.style.display = "none";
            location.reload();
        }
    };
    ...
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM