2013-10-31 30 views
-1

我使用History.js(jquery.history.js v1.8b2)。 Chrome版本30.0.1599.101米。當我從外部鏈接導航回來時,是否應該觸發window.statechange?

我無法弄清楚如何讓History.js以我期望的方式工作。

我有一個頁面,有兩個鏈接。第一個模擬ajax操作。它只是將頁面中的<h2>中的文本從「開始」更改爲「2」。第二個鏈接僅指向google.com。

這是我做的:

  • 清除高速緩存中的鉻
  • 加載頁面
  • 點擊第一個鏈接(我稱之爲pushState的,statechange發生有更新我的文字爲「2」)
  • 單擊google.com鏈接(轉到谷歌)
  • 單擊瀏覽器後退按鈕。

當後退按鈕單擊時,我期望應該調用statechange處理程序,然後我會得到我的狀態對象,以便我可以將文本恢復爲「2」。

但處理程序沒有被調用。所以我的頁面留下了文本「開始」(緩存頁面在瀏覽器中)。有趣的是,url被設置爲我在pushState調用中推送的「2」版本。

我錯過了什麼嗎?這是我的代碼:

<h2 id="state">start</h2> 

<a id="2" class="button" href="#">Goto State 2</a> 

<a href="http://google.com">Goto google</a> 

<script type="text/javascript"> 

    $(function() { 

     History.Adapter.bind(window, "statechange", function() { 
      console.log("statechange called"); 

      var state = History.getState(); 

      if (state.data.mystate) { 
       // Restore the old state 
       $("#state").text(state.data.mystate); 
      } else { 
       // Start state 
       $("#state").text("start"); 
      } 
     }); 


     $(".button").click(function(e) { 
      // push the state we're transitioning to 
      var newState = $(this).attr("id"); 

      History.pushState(
       { mystate: newState }, 
       "at state " + newState, 
       "http://localhost:50494/PushState?state=" + newState); 

      // statechange will be called now, and we'll update the page from our newState 

      e.preventDefault(); 
     }); 


    }); 

</script> 

回答

0

我認爲答案是否定的,statechange不應該被稱爲從頁面外導航回來。

我注意到http://browserstate.github.com/history.js/demo/的演示程序正如我所期望的那樣工作,所以我做了一個視圖源以查看它是如何工作的。從我可以告訴的是,這裏是你應該如何使用History.js。

  1. 加載頁面時,請查看History.getState()。data。 如果您認識到您的某個州有,那麼這意味着您正在從不同的頁面導航回到您的頁面,例如從您去過的外部鏈接。 (注意:瀏覽器可能剛剛從緩存中加載了頁面,或者它可能已從服務器重新加載,因爲要使用剛剛找到的狀態更新頁面/ UI)。因此,請將您的網頁更新爲該狀態。 如果您不承認狀態,那麼就您的網頁而言,這是首次加載。適當地啓動。
  2. statechange事件將在頁面內「ajax」狀態之間的瀏覽器後退/前進按鈕(在此頁面顯示的狀態)中被調用。 當您調用pushState()時,它也會被調用。呃,難道不是這樣嗎?是的,所以當你要過渡到自己的網頁中一個新的狀態,遵循此模式:
  3. 準備好你的狀態對象(可能涉及Ajax調用),
  4. 呼叫pushState(yourObject,...)
  5. 不要更新頁面/你還沒有。
  6. 你實際上更新你的頁面/ ui從statechanged處理程序將被調用一會兒。

我錯誤地認爲你應該做所有的更新頁面的工作,然後推後狀態。這隻會讓事情變得困難,因爲statechanged也會被調用。

此外,看起來總的來說,您應該在您所在的一個頁面內將狀態推送爲類似於ajax的轉換。不要將狀態推送給您在頁面之外關注的鏈接(除非您真的瞭解所有這些內容,並且正在嘗試做某些事情)。

我在這裏更新的代碼示例展示什麼工作對我來說現在:

<h2 id="state">start</h2> 

<a id="2" class="button" href="#">Goto State 2</a> 

<a href="http://google.com">Goto google</a> 


<script type="text/javascript"> 

    $(function() { 
     // page loading, check for available state I recognize 
     var availableState = History.getState(); 

     if (!availableState.data.mystate) { 
      // loading for the first time 
      $("#state").text("start"); 
     } else { 
      // load from the available state 
      loadState(availableState); 
     } 

     History.Adapter.bind(window, "statechange", function() { 
      var state = History.getState(); 
      loadState(state); 
     }); 

     function loadState(state) { 
      if (state.data.mystate) { 
       // update the page to this state 
       $("#state").text(state.data.mystate); 
      } else { 
       // update the page to the initial state 
       $("#state").text("start"); 
      } 
     } 


     $(".button").click(function (e) { 
      // The user clicked a button, so we want to transition to a new state 
      // in this page. Push the state we're transitioning to (which we've hidden 
      // in the id attribute in this example). 
      var newState = $(this).attr("id"); 

      History.pushState(
       { mystate: newState }, 
       "at state " + newState, // title 
       "?state=" + newState); // url 

      // statechange will be called now, and we'll update the page from our newState 

      e.preventDefault(); 
     }); 


    }); 

</script> 
相關問題