2012-11-27 52 views
2

我試圖找到一個乾淨的解決方案,以最有效的方式使用瀏覽器歷史記錄。 (我使用GWT,但這個問題確實是比這更普遍)瀏覽器歷史記錄管理

這裏是我的情況(我認爲這是非常標準):

我有了幾個不同的頁/地方的Web應用程序/位置(無論您想要調用它),我將顯示這些位置以響應瀏覽器歷史記錄的更改。除了通常的「首頁」,「功能」,「聯繫人」等大多是靜態HTML頁面之外,還有一個「用戶」部分,用戶可以登錄他們的用戶帳戶(我們稱之爲)「項目」部分,用戶可以在其中進行項目工作。

所以,現在我只需使用一個名爲#Home#Features#Contact等,以及#User#工程才能到不同的頁面本地鏈接。並且一切都很好,除了以下場景:

如果有人打開鏈接#項目,例如,該人員會顯示一個項目登錄對話框。此登錄對話框有一個取消按鈕,我希望通過簡單地調用瀏覽器的返回按鈕從我的應用程序(很簡單)實現。我想這樣做的原因,有兩個方面:

  1. 你可以從在應用幾個不同的位置,以及你的書籤此登錄對話框,並用這種方法,我就不需要跟蹤用戶來自哪裏。
  2. 更重要的是:如果我不是沒有記住用戶從(如#Home)來和鏈接用戶「前進」回到那個地方,我得到以下效果:
    • 比方說,用戶訪問#家庭,然後#功能,然後單擊項目登錄。
    • 如果用戶點擊取消按鈕,我送他「前進」到#Features,在瀏覽器上的按鈕,點擊之後會帶回的登錄對話框,然後再次#Features最後#首頁。不是你所期望的。
    • 相反,你會想回到#Home立即,只是你會得到什麼,如果我簡單地實現通過瀏覽器的後退功能取消

此時一切都很好,除了當用戶通過直接書籤鏈接到#工程最初進入這個登錄對話框。因爲如果我只是有取消 = 返回,用戶將被從網頁發回到他的瀏覽器的開始頁面或他以前的任何位置。所以,在這種情況下,我確實需要鏈接「轉發」到#家電

現在,我試圖想幾種方法來解決這個問題,並想出了一個解決方案夫婦的,但沒有一個在我看來非常可取的,但讓我反正分享他們或許炒作一些創造力:

  • 當頁面第一次打開時,抓取歷史令牌。如果是#工程#User或其他任何觸發取消對話框,將下面的項目到歷史堆棧:#Home#工程,其中最後一個是保存的初始令牌。那麼,這可以讓我取消按鈕的功能正確......一旦...但是,如果用戶點擊事後,他將獲得再次登錄對話框(因爲原來的歷史令牌仍處於歷史堆棧我不知道如何清除它)。點擊取消然後會將他從頁面中移除(不一致的行爲)。
  • 我可以改爲放置#+++#Home#工程到堆棧中,那麼這將讓我趕上點擊,將通過檢測需要用戶在頁面#+++鏈接,並簡單地重新添加#主頁令牌到堆棧上。這樣就解決了問題,整體工作很漂亮,但我不喜歡的網站,不要讓你背出他們不迅速錘擊後退按鈕足夠了...
  • 最乾淨的解決辦法是,如果我能以某種方式跟蹤歷史堆棧的長度與我應用中的位置有關。在開始時足夠簡單:它上面有一個項目。但是如果我得到這樣的一系列地點:#家庭#特色#家庭?用戶是否點擊返回回到#家庭,即歷史現在在瀏覽器中是長度1,或者他點擊了#家庭鏈接,即歷史是長度3?我檢測,這將是想法:
    • 定義,即#Home相同#home
    • 使頁面中的所有鏈接僅鏈接到鏈接的大寫版本。
    • 每當您收到以 大寫字母開頭的歷史更改通知時,請立即向歷史記錄添加兩個項目,第一個以小寫字母開頭,第二個以大寫字母開頭。即#Home變成#Home#home#Home
    • 如果你有機會與一個小寫字母開頭的歷史變化,你知道用戶只需點擊,而不是一個鏈接,你只需點擊兩次爲他真正得到回上一頁。
    • 現在您可以區分「後退」和「前進」鏈接,並在代碼中保留精確的歷史記錄模型。
    • 但是,不幸的是,有兩個問題:第一,瀏覽器歷史雜亂無章(不是很優雅),第二,系統開始崩潰,如果用戶點擊足夠快您的應用沒有時間對消息做出反應。

看起來這應該是一個非常普遍的問題,我希望你們可以點我更有用的方向上比我的想法至今。

+1

您是否考慮過使用客戶端路由系統(如angularjs提供的路由系統)? http://angularjs.org它可以使用html5的推送權益來跟蹤後退和前進,併爲您提供處理直接到達路線的客戶的工具。 – SuitedSloth

+0

@thatjuan angularjs似乎功能非常豐富,可能需要一段時間才能篩選出來。你是否足夠了解它在幾句話中總結了與我的問題相關的部分?這將是非常有益的,謝謝。 –

+0

你看過活動和地方嗎? https://developers.google.com/web-toolkit/doc/latest/DevGuideMvpActivitiesAndPlaces你試圖發明自己的解決方案的任何理由? –

回答

1

window.history有一個length屬性,該屬性將顯示當前選項卡的歷史記錄中有多少條目。不幸的是不是可過濾(所以沒有辦法說window.history.localURLs.length)。

如果您幾乎完全在客戶端(即部分更新,很少整頁加載,使用哈希或API),那麼您可能需要考慮將客戶端路由框架合併到您的應用程序以避免重新發明車輪。

+0

好!這正是我期望的簡單細節,它可以幫助我解決這個問題。現在,我需要做的只是在頁面第一次加載時存儲history.length,然後讓我的「後退」功能檢查是否有東西要回去,如果沒有,請將它變成「主頁」鏈接!甜!謝謝!我很驚訝GWT不公開這個。它完全跨瀏覽器嗎?我現在就試試。 –

+1

ARGH!它幾乎可以工作!除了它返回的歷史長度不僅僅是我仍然可以點擊「返回」的次數,還包括了我可以點擊「前進」的次數!因此,它不再工作...是否有一個等價物只返回「後退」計數? –

+0

@Markus - 不幸的是,沒有。 –

0

你怎麼樣有一個Queue<String> historyQueue;

當首次加載頁面,即onModuleLoad()你initalize的Queue。 當您捕獲歷史事件時,請檢查其是否有歷史記錄或新記錄令牌。 如果它返回,則將其從隊列中彈出,如果它是新的,則將其添加到隊列中。這樣,取消按鈕只是一個token = historyQueue.pop()並檢查標記是否爲空。如果是這樣,那麼就像你說的back = cancel,所以只要做適當的事情。

+0

這將是一個很好的解決方案,除了兩個問題:不幸的是,我不認爲有一種可靠的方法來檢測頁面更改是「前進」還是「後退」更改。而且,更糟糕的是,如果這是可能的話,那麼您可能無法正確處理許多瀏覽器在歷史中隨機跳轉的能力。 –

1

在用戶可以訪問#LOGIN對話框之前,將執行入口點類。在這堂課你可以記住最後一個已知的頁面。在登錄活動/演示者中,您可以添加瀏覽器歷史記錄事件處理程序,該處理程序會檢查最後一個已知位置是否爲空。如果爲null,則將用戶發送到#HOME頁面。

您無需向瀏覽器詢問用戶訪問過您應用中的哪些位置。如果您想要:[#HOME,#LOGIN,#FEATURES,#HOME],您可以記住每個會話的整個歷史記錄。

+0

如果用戶使用瀏覽器的歷史記錄按鈕隨機瀏覽,我該如何確保正確記住歷史記錄?我所能做的就是保持自己的歷史,即假設每一步都是「前進」的舉動。因此,如果用戶點擊「主頁」,「功能」,返回,那麼我的歷史記錄現在將包含「主頁」,「功能」,「主頁」,瀏覽器的歷史記錄是否僅包含「主頁」。不知道我明白我該如何使用它來做出關於如何處理對話取消點擊的決定? –

+1

在你原來的問題中,你描述了一個非常具體的問題:回到另一個網站。您只需要知道您自己的歷史記錄是否爲空即可解決該問題。除此之外,讓瀏覽器管理歷史。 –

+0

不幸的是,這並不能提供給我這些信息。我永遠無法分辨用戶是否回到「空」狀態。假設我看到頁面轉換「Home」,「Features」,「Home」(從上面)。用戶現在是否處於BACK將我帶離頁面的位置?或回到「功能」?即通過單擊「返回」或「功能」頁面上的鏈接或其他書籤的某個位置,他是否可以訪問第二個「主頁」?這是我需要解決的細節。 –