2012-08-17 84 views
8

我有以下的測試程序:http://dev.driz.co.uk/ajax/使用後退和前進按鈕與歷史API

您可以點擊的鏈接使用jQuery AJAX在其他頁面加載和有兩種類型,globalTabs和localTabs其負載內容分成不同的面板。注意:每個頁面實際上是完整頁面,但我們只使用jQuery查找方法獲取我們想要的內容。

爲了加強這一點,我使用了HTML5 History API(用於跨瀏覽器的History.js)。

標題和網址更改正常,歷史堆棧被推送成功,當我使用後退和前進按鈕時,網址和標題將恢復。

現在複雜的部分從前一狀態加載回內容並且更復雜地加載正確的類型,例如,全球或本地ajax。爲了實現這一點,我想我需要傳遞數據和類型到推狀態,以便它可以重新用於popstate ...

任何人都可以幫助指向正確的方向嗎?我有所有的第一部分工作,只是將ajax類型傳遞給pushState,然後重複使用popstate更改的情況。

要在此我重寫它改進如下,以顯示我的計劃傳遞的類型和數據:

注:大寫歷史是因爲我使用History.js

var App = { 

    init: function() { 

     $(document).ready(function() { 

      $('.globalTabs li a').live('click', function (e) { 
       e.preventDefault(); 
       App.globalLoad($(this).attr('href')); 
      }); 

      $('.localTabs li a').live('click', function (e) { 
       e.preventDefault(); 
       App.localLoad($(this).attr('href')); 
      }); 

     }); 

     window.addEventListener('popstate', function(event) { 

      // Load correct content and call correct ajax request... 

     }); 

    }, 

    localLoad: function (url) { 

     $.ajax({ 
      url: url, 
      success: function (responseHtml) { 
       $('.localContent').html($(responseHtml).find('#localHtml')); 

       $data = { $(responseHtml).find('#localHtml'), 'local'}; 

       History.pushState($data, $(responseHtml).filter('title').text(), url); 
      } 
     }); 

    }, 

    globalLoad: function (url) { 

     $.ajax({ 
      url: url, 
      success: function (responseHtml) { 
       $('.mainContent').html($(responseHtml).find('#globalHtml')); 

       $data = { $(responseHtml).find('#globalHtml'), 'global'}; 

       History.pushState($data, $(responseHtml).filter('title').text(), url); 
      } 
     }); 

    } 

}; 

App.init(); 

更新:爲了澄清這個問題,他們是我尋求幫助的兩個問題。

1.)獲取後退和前進按鈕與ajax請求一起工作,以便他們將正確的數據加載回內容區域。

2.)將內容加載到正確的區域,同時也通過pushState方法傳遞內容,以便它知道它是全局div還是本地div請求。

回答

12

數據對象是錯誤的,這就是爲什麼你得到這個問題。一個對象被定義鍵,值對:

object = {key:'value'}; 
$data = { text:$(responseHtml).find('#globalHtml'), type:'global', url:'the_url'}; 

$data = { $(responseHtml).find('#globalHtml'), 'global'}; 

使用對象定義你會得到使用歷史數據。的getState()

History.Adapter.bind(window,'statechange',function(){ 
    var data = History.getState().data; 
    if(data){ 
     var html = data.text; 
     var type = data.type; 
     var type = data.url; 
     if(html && type){ 
      if(type == 'global'){ 
       // just change html 
       $('.mainContent').html(html); 
       // call the App object's function 
       if(url) App.localLoad(url); 
      }else{ 
       $('.localContent').html(html); 
      } 
     } 
    } 
}) 

注:

  • 時stateChange事件得到的發射,如果任何數據出現時,它會觸發Ajax調用
  • 模擬Ajax調用,而不使其僅僅更改標題還我認爲,這將覆蓋它

編輯

  • 數據對象實際上是從History.getState()拍攝。數據未History.getState()
  • 增加了另一個參數去存儲的對象使用URL和類型保存URL
  • 您可以將呼叫相同的功能,在onClick事件

問題:

Uncaught TypeError: Converting circular structure to JSON

一個目的是某處引用本身;因此信息「圓形結構」。這意味着您正在嘗試對具有對自身的引用的對象進行串聯,這通常會發生在DOM元素上。你真的應該考慮改變

$data = { $(responseHtml).find('#localHtml'), 'local'}; 

到:

$data = { html:$(responseHtml).find('#localHtml').html(), type:'local'}; 

通知的按鍵爲對象(HTML和類型)和HTML函數調用(html的()),這樣你就不會發送不必要的數據,只是HTML。如果你需要加載它作爲一個DOM對象時使用的HTML數據只是用這樣的:

var DOM_Element_loaded = $('<div>').html(html_loaded); 

現在你可以在無需將其附加到身體加載HTML中使用DOM_Element_loaded搜索/操縱數據。

+0

那麼我該如何解僱?你沒有提到popstate?因爲我需要做的是在用戶使用後退和前進按鈕時更改內容,然後改變標題(有效地複製ajax調用所做的),而不是使用ajax,它將使用歷史數據,因爲沒有點重新加載它顯然。 – Cameron 2012-08-25 11:15:12

+0

我也收到錯誤:'Uncaught TypeError:將圓形結構轉換爲JSON'任何想法有什麼不對? http://dev.driz.co.uk/ajax/ – Cameron 2012-08-25 12:04:18

+0

編輯我的迴應,關於json錯誤,只檢查你是否傳遞簡單對象,沒有功能 – cuzzea 2012-08-25 18:10:16

0

注意:這實際上是一個比答案更多的評論,但是您可以通過答案響應獲得更好的語法高亮顯示。

這就是我遇到這個問題時所做的。如果我沒有記錯,這就避免了雙重請求問題。

window.onpopstate = function(event) { 
    if (event.state && event.state.initialHref) { 
    // make an AJAX request 
    // URL for AJAX request is event.state.initialHref 
    } 
} 

當我使用history.pushState()/history.replaceState(),我定義的對象的initialHref屬性爲第一個參數。我爲此值使用絕對URL,而不是相對值。