2012-10-11 22 views
5

我有一個簡單的網頁,即:如何讓Firefox在從不同域的頁面返回時觸發popstate事件?

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<title>History hacks</title> 
<script> 
window.onpopstate = function (e) { 
    alert("location: " + document.location + ", state: " + JSON.stringify(e.state)); 
} 
window.onload = function (e) { 
    alert('page loaded'); 
} 
</script> 
</head> 
<body> 
<p> <a href="http://www.yahoo.com">Yahoo</a> <a href="#part1">Part 1</a></p> 
</body> 
</html> 

現在有關於Chrome和Firefox如何觸發popstate事件(我不敢想我要對付我避開了一些分歧測試IE),但是在這裏給我帶來問題的是,Chrome會觸發一個popstate事件,只要我點擊這兩個鏈接中的任何一個,然後再點擊後退按鈕。 Firefox會觸發改變哈希部分的鏈接的事件(只有第一次,如果哈希鏈接是相同的),並且如果我點擊雅虎鏈接然後單擊後退按鈕,將不會觸發它。

那麼有什麼方法可以告訴我,Firefox用戶剛剛點擊並從另一個域上完全不同的站點返回到我的頁面?是否有另一個事件可以在Firefox中用於此目的? (當我從yahoo.com返回時,負載事件不會被觸發。)

回答

1

如果您希望在返回時顯示頁面時通知pageshow事件,即使它返回緩存在頁面緩存中。

請注意,如果沒有加載事件,也意味着該頁面仍然具有完全相同的DOM和腳本執行環境,它在導航時完成。基本上,就好像用戶切換標籤一段時間,而不是導航。

因此,你還想在這種情況下得到一個事件嗎?當用戶切換回帶有您的頁面的選項卡時,是否會收到您要查找的事件?

9

要獲得當回(或轉發)按鈕用於轉到初始頁面加載一個popstate事件,使用replaceState()

window.onload = function(e) { 
    history.replaceState(null, null, document.URL); 
} 

頁面加載時要忽略瀏覽器生成初始popstate只要您致電pushState/replaceState,您可以標記狀態,例如

history.pushState({myTag: true}, null, url); 

那麼你popstate處理程序只是過濾器myTag

window.onpopstate = function(e) { 
    if (!e.state.myTag) return; // none of my business 
    // code to handle popstate 
} 

您可以爲一個微不足道的跨瀏覽器解決方案結合這兩種:

window.onpopstate = function(e) { 
    if (!e.state.myTag) return; // none of my business 
    // code to handle popstate 
} 

window.onload = function(e) { 
    history.replaceState({myTag: true}, null, document.URL); 
} 

@Boris Zbarsky有詳細的bfcache。我沒有想過如何將這與我的方法結合起來。我只是adding a page unload handler

window.onunload = function(e) { } 
+0

這是說明如何使歷史API的工作方式相同的跨平臺有很大的答案,但它實際上並沒有回答OP的問題:**如何判斷用戶是否實際點擊了「返回」以結束頁面**使用您的示例,您可以知道用戶點擊了Chrome和Safari,因爲mypop在onpopstate處理程序中不會爲空。然而,在Firefox中,onpopstate不會被調用,所以似乎無法確定用戶是否返回頁面,或者是否是第一次訪問。那麼是否有任何方法可以在Firefox中區分這一點? – Karmacon

+1

@Karma:如果您禁用bfcache(請參閱我的答案的最後部分),那麼Firefox的行爲應與Chrome相似。但請閱讀Boris Zbarsky的回答,爲您解釋爲什麼您應該更喜歡Firefox的頁面緩存以適應Chrome的行爲。 –

+0

謝謝@Sean Hogan。在重新閱讀Firefox bfCaching之後,我意識到它不適用於我的網站,因爲我們使用https。 Firefox總是刷新頁面。我想我無能爲力。 – Karmacon

0

卸載之前禁用它,我刷新我的網頁(獲得初始狀態),然後設置新的href

window.onunload = function(e) { 
 
    location.reload(); 
 
    location.href = **new_url** ; 
 
}

我必須這樣做,因爲Firefox的節約我的頁面的最後狀態並恢復它而不是重新創建它。

0

我有同樣的問題,不得不挖掘規範,找出爲什麼popstate事件不會在任何瀏覽器觸發時,後退按鈕用於從不同域上的頁面返回。事實證明,popstate不應該在這種情況下觸發,因爲文檔的狀態改變是不正確的,popstate只有在狀態改變爲真時纔會觸發。對於狀態改爲被設置爲true規範說:

讓狀態改變,如果指定條目的文檔有一個最新的條目,該條目不指定條目是真實的;否則就是假。

我的理解是,當我們從不同領域的頁面返回到我們的頁面時,我們的頁面沒有最新條目,因爲文檔已經更改並且新文檔還沒有最新條目。再次來自規範:

瀏覽上下文中的每個文檔也可以有最新的條目。這是瀏覽上下文會話歷史記錄最近遍歷的文檔的條目。在創建文檔時,它最初沒有最新條目。

但是仍然有方法,如果用戶已經回來到您的網頁使用歷史的pushState的或replaceState方法在你的頁面中history.state設置一個標誌並檢查此標誌history.state的存在在頁面加載。

對於WHATWG的HTML多讀符合規範處理popstate事件的一部分: https://html.spec.whatwg.org/multipage/browsers.html#history-traversal

相關問題