為什麼Ajax無法跟蹤瀏覽曆史?
我們假設,僅僅是假設:輸入一個URL訪問某網站時,瀏覽器背後就會記錄你當前訪問的URL,緊接著從當前頁面點擊一個連結跳轉到新頁面,瀏覽器就
會把剛剛訪問的那個URL記錄在歷史裡邊,這樣你點[上一頁] 按鈕時,它就知道要回到剛剛那個頁面。想必這樣的過程應該是挺容易理解的。
那麼Ajax為什麼不能跟蹤呢?
Ajax請求往往是你頁面的某個按鈕觸發了點擊事件(可以是其他事件!)而發送的。
如果你在當前頁面點擊了某個按鈕觸發了Ajax請求發送,然後看到了一副風景畫,突然覺得很有feel,把地址複製給好友叫他去看。這時,他訪問了這個地址,發現看到的不是你看到的內容,因為他沒有去點擊那個按鈕,導致Ajax請求沒有被發送。
所以我們需要尋求一種方法去跟蹤曆史。
Iframe跟蹤曆史
想必大家都知道iframe就是頁面上一個新的小頁面,在iframe上跳轉是可以記錄到當前頁面的瀏覽曆史的。
大家可以去看看QQ郵箱裡邊的結構。使用者在做任意操作,均為局部重新整理(只重新整理iframe內容),並且使用者可以使用後退按鈕回到上個操作!
從URL入手
回到主題,那我就是喜歡Ajax的話應該怎麼做?外語屋
既然我想要複製URL分享當前看到的東西,那我肯定要從URL去入手,如果說我將location.href(也就是當前的url)改變了,當前頁面就會跳轉到改變後的URL。
那麼URL怎麼改變,當前頁才不會重新整理呢?
有用過錨的人就知道,URL後邊的#部分就是hash部分,改變這段值頁面是不會跳轉到新頁面也不會重新整理。
如果說我們發送一個Ajax請求後,自動改變當前的URL的hash部分。
這樣把地址複製給他人的時候,頁面可以拿到該hash然後根據其值發送對應的Ajax請求並做同樣地處理,這樣就可以跟蹤瀏覽曆史了。
修改hash以及響應hash改變的事件
除了IE8以下的IE系列外,其他瀏覽器均支援window.onhashchange
來監聽URL的hash變化,至於如何修改hash一會給代碼就知道。
那麼為了相容IE8以下版本的IE,需要用定時器來監聽URL上的hash變化,當然會消耗效能了,沒辦法,天朝底下到處都用萬惡的IE,你得為他們考慮可用性。
下邊貼個代碼:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<meta charset="gbk">內陸運輸
</head>
<body>
<button onclick="changeHash()">Click Me</button>
<script language="javascript" src="hashchange.js"></script>
</body>
</html>
/**
* hashchange.js
* @author raphealguo(raphealguo@qq.com)
* @date 2011/08/09
*/
var nextHash = 0, //下一個hash值,每次會遞增
curHash = '';//記錄當前hash
if ("onhashchange" in window) {//IE8以下版本的瀏覽器不支援此屬性
alert("The browser supports the hashchange event!");
}
function getHash(){//擷取hash
var h = location.hash;
if (!h){
return '';
}else{
return location.hash;
}
}
function changeHash(){//修改hash 每次點擊按鈕觸發hash變化
/*
發送Ajax請求時,可以修改相應的hash值,
只要在頁面load完之後擷取hash值並發送對應的Ajax請求並更新頁面,
這樣就可以達到用Ajax也能跟蹤瀏覽曆史的目的
*/
location.hash = "#" + nextHash++;
}
function changeHashCallBack(){//hash變化之後,回呼函數會被觸發
var hash = getHash();
if (curHash != hash){
curHash = hash;
alert("雜湊更改 :" + hash);
}
}
if (document.all && //辨別IE
!document.documentMode//IE8才有documentMode
){
/* 低於IE8的IE系列採用定時器監聽 */
setInterval(changeHashCallBack, 100);
alert('<IE8');
}else{
window.onhashchange = changeHashCallBack;
}
可以看到,當按鈕點擊時, 僅僅觸發的是getHash函數,而changeHashCallBack是通過監聽/window.onhashchange 的機制來觸發的。
另外jQuery的一個外掛程式:jQuery HashChange 也是可以支援hashChange,但它沒有使用原生態的window.onhashchange ,Firefox等瀏覽器底下也是採用定時器監聽的辦法去監控hash是否改變,這點個人認為不好,並且此外掛程式還得依託jQuery,真的還不如模仿上邊的代碼,自己寫一下。
本篇總結
身處在Web前端,就應該讓使用者體驗更強更好的互動,當然了這裡邊包括了很多很多方面:
可用性、方便性(本文寫的就是我認為的其中一種方便性)、效能(不至於搞垮瀏覽器崩潰)、安全性、人性化(考慮殘疾人群)……
身為Web前端開發的你是否經常考慮這些問題!?