Ajax – 解決上一頁下一頁問題 jquery.history plugin

相信有開發 Ajax 網站的人都有遇到這個問題,在跟後端溝通的時候使用 javascript 來做到 Ajax 效果的確是讓使用者感覺很順暢。但是在想要回到上一步的時候會習慣性點下上一頁,這時候頁面的反應卻不是預期中的。

jquery.history plugin

為了解決這個問題,網路上也有蠻多解決方案的,jquery.history plugin 剛好就是其中一種。其實它的原理也蠻簡單的,在網址列中的 “#” 後面的字串修改瀏覽器是並不會有任何動作的(單純增加一個”#”是回到TOP),其他情況下的修改,瀏覽器都是會重新去 server 上要求一次資料(也有可能在瀏覽器中的 cache 存在就不會重新要求了,但是也算是 reload 的動作),但是瀏覽器還是會記錄網址的變動,可以隨便拿一個網站試試看。所以在這個 plugin 中,利用這個原理他監控每一次網址列”#”後面的變動,當變動的時候就去觸發 javascript 內部的處理程序。

Implement

官網有Demo可以參考,在這邊我是用Asp.Net Mvc3 預設內容來做

image

當然最重要的就是先把 plugin include 進來啦,再來參考官網上面的範例小調整一下

(function ($) {
function loadContent(hash) {
if (hash != "") {
hash = hash.replace(/W/, '');
try {
eval("ajax" + hash + "();");
}
catch (err) { }
}
}

$(document).ready(function () {
$.history.init(loadContent);
$('#menu a').not('.external-link').click(function (e) {
var url = $(this).attr('href');
url = url.replace(/^.*#/, '');
$.history.load(url);
return false;
});
});
})(jQuery);

 

這邊主要分成兩個部分,$(document).ready 還有 loadContent(hash) 在 $(document).ready 的時候設定初始化 history 而且傳入loadContent 這個當作設定控制的 function ,然後設定 $(‘#menu a’).not(‘.external-link’)  click 的時候觸發。loadContent(hash) 這邊傳入的 hash 就是網址列中 “#” 後面的字串。在這邊做法我有小調整,當 #Home/About 的時候我會去呼叫 ajaxHomeAbout() 這個 function ,再從中去處理這邊要有的動作。

 

<li><a href="#Home/About">About</a></li>

function ajaxHomeAbout() {
$.ajax({
url: "/Home/About/Panel",
type: "GET",
data: "",
success: function (html) {
$('#main').html(html);
}
});
}

 

這樣子基本上就有支援了上一頁下一頁的動作。但是也發現了幾個問題。

1.當網址列固定的時候並不會觸發 javascript 動作

可能需要有某個連結是當按下的時候做判斷而執行不同動作,但是在這邊卻沒有觸發到動作,如果這邊執行的狀態是不需要保留的,可以在每一次動作加上一個 guid 然後在 hash 解析的時候再移除掉。

 

var url = $(this).attr('href');
url = url.replace(/^.*#/, '') + "?" + Guid();

 

hash = hash.replace(///g, "");
hash = hash.replace(/?.*/, "");

 

regex 沒有很熟練所以我用了兩次 replace,這樣可以在每次被點擊的時候都確定去執行動作。

如果需要保留狀態的話,就需要改變 href 的值,或是用其他方式經過 hash 去保留才能夠在複製貼上網址列的時候保留狀態。

 

2.有些動作是有相依性的,沒有辦法在複製貼上超連結的時候直接進入

例如說我在 /Home/About 下加入了一個 hidden 的 div ,當我進入之後點下 show 的超連結便會顯示,當下的 url 是 http://localhost/#Home/About/ShowDiv 可是當我重新開一個視窗將網址貼上的時候,他怎麼傻傻地留在 http://localhost/ 的畫面。這個動作必須先執行 #Home/About 再去執行 #Home/About/ShowDiv 才是正確的,這個 plugin 雖然會在 init 的時候去執行 # 後面動作,不過沒有聰明到知道這些動作的相依性。jQuery History Plugin MVC Sample 這邊範例網站有一個範例就是雙層情況下使用 jquery.history 。就是利用拆解字串的方式去實作這個部分。

 

3.當 click 事件的時候,我們可以得到 this 的參數,不過透過 jQuery.history 就取不到 this 參數

這邊的解法應該就是利用 id 或其他屬性來串了,如果整個 this Json 之後傳入 Url 應該會超過預設長度。

4.SEO

大量使用 Ajax 的網站應該都會遇到這個問題,google 有一些建議

Making AJAX Applications Crawlable

http://code.google.com/intl/en/web/ajaxcrawling/docs/getting-started.html

https://docs.google.com/present/view?id=dc75gmks_118gk53qdg6&interval=5&pli=1

Reference

jQuery history plugin

http://tkyk.github.com/jquery-history-plugin/

JavaScript 模式產生 GUID

http://blog.blueshop.com.tw/jeff377/archive/2007/11/07/53275.aspx

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *