不重新整理改變URL: pushState + Ajax

來源:互聯網
上載者:User

標籤:blog   http   io   os   使用   ar   strong   div   sp   

如果你玩過Google+,看到過YouTube的新介面,便會體驗到這個HTML5的新功能。使用pushState + Ajax(pjax),可以實現網頁的ajax載入,同時又能完成URL的改變而沒有網頁跳轉重新整理的跡象,就像是改變了網頁的hash(#)一樣。

指引 / 跳至 

  • 1 舊的解決方案
  • 2 新的解決方案: pushState
    • 2.1 HTML5 的 pushState+Ajax
    • 2.2 pushState 例子
    • 2.3 Demo 示範
    • 2.4 replaceState 同理
    • 2.5 pushState、replaceState 的區別
  • 3 限制因素
  • 4 Ajax 配合 pushState 例子
  • 5 pushState 配合 popstate 監聽
    • 5.1 流程圖示意
  • 6 jQuery + PJAX 外掛程式
舊的解決方案

曾說SEO和ajax是天敵。此前從Twitter開始流行Ajax+hash的方式調用內容,Google給出的解決方案是“#!~string”自動轉換為“?_excaped_fragment_=~string”來抓取動態內容。但這無疑會非常麻煩:首先你需要對網站進行“?_excaped_fragment_=~string”的處理配置,而且,如果使用者把網址“http://example.com/#!/~string”直接複製並分享的話,意味著網頁還必須監聽hashchange。不過如果你覺得這個#!很好看就沒關係了。

新的解決方案: pushState

然而HTML5的新介面pushState / replaceState就可以比較完美的解決問題,它避免了改變hash的問題,避免了使用者不理解URL的形式感到疑惑,同時還有onpopstate提供監聽,良好響應後退前進。而且它不需要這個URL真實存在。

HTML5 的 pushState+Ajax

HTML5提供history介面,把URL以state的形式添加或者替換到瀏覽器中,其實現函數正是 pushState 和 replaceState。

pushState 例子

pushState() 的基本參數是:

window.history.pushState(state, title, url);

其中state和title都可以為空白,但是推薦不為空白,應當建立state來配合popstate監聽。

例如,我們通過pushState現改變URL而不重新整理頁面。

var state = ( {

url: ~href, title: ~title~additionalKEY~additionalVALUE

} );

window.history.pushState(state, ~title~href);

其中帶有“~”符號的是自訂內容。就可以把這個~href(URL)推送到瀏覽器的歷史裡。如果想要改變網頁的標題,應該:

document.title= ~newTitle;

注意只是pushState是不能改變網頁標題的哦。

Demo 示範

點我試試 (實現函數onclick = history.pushState( null, null, ‘/test-string‘); )。實際上這個部落格在文章之間也部署了這個技術。

replaceState 同理

window.history.replaceState( state, ~title, ~href);

pushState、replaceState 的區別

pushState()可以建立曆史,可以配合popstate事件,而replaceState()則是替換掉當前的URL,不會產生曆史。

限制因素

只能用同域的URL替換,例如你不能用http://baidu.com去替換http://google.com。而且state對象不儲存不可序列化的對象如DOM。

Ajax 配合 pushState 例子

現在用Ajax + pushState來提供全新的ajax調用風格。以jQuery為例,為了SEO需要,應該為a標籤的onclick添加方法。

$("~target a").click(function(evt){

evt.preventDefault(); // 阻止預設的跳轉操作

var uri=$(this).attr(‘href‘);

var newTitle=ajax_Load(uri); // 你自訂的Ajax載入函數,例如它會返回newTitle

document.title=newTitle; // 分配新的頁面標題

if(history.pushState){

var state=({

url: uri, title: newTitle

});

window.history.pushState(state, newTitle, uri);

}else{ window.location.href="#!"+~fakeURI; } // 如果不支援,使用舊的解決方案

return false;

});

function ajax_Load(uri){ ... return newTitle; } // 你自訂的ajax函數,例如它會返回newTitle

即可完成pushState。至於新標題newTitle的擷取就是另外的問題了,例如你可以為a標籤分配data-newtitle=~title屬性並屆時讀取,或者如果你用的$.ajax()函數,可以用$(result).filter("title").text()來擷取。

另外如果需要對新載入的頁面的串連同樣使用這個ajax,則需要對新內容的a標籤重新部署,例如

$("~newContentTarget a").click(function(evt){ ... });

pushState 配合 popstate 監聽

想要良好的支援瀏覽器的曆史前進後退操作,應當部署popstate監聽:

window.addEventListener(‘popstate‘, function(evt){

var state = evt.state;

var newTitle = ajax_Load(state.url); //你自訂的ajax載入函數,例如它會返回newTitle

document.title=newTitle;

}, false);

提醒,你可以通過setRequestHeader()來讓伺服器端配合你的ajax請求輸出專門的內容。

流程圖示意

這個例子的大致過程如所示

jQuery + PJAX 外掛程式

已經在github上發布,有人把PJAX做成了jQuery外掛程式,方便調用,節省大量代碼:

if ($.support.pjax) {

$(document).on(‘click‘, ‘a[data-pjax]‘, function(event) {

var container = $(this).closest(‘[data-pjax-container]‘)

$.pjax.click(event, {container: container})

});}

謝謝收看,如有不正請指出。

 

http://blog.netsh.org/posts/pushstate-ajax_1339.netsh.html

不重新整理改變URL: pushState + Ajax

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.