JavaScript不刷新實作瀏覽器的前進後退功能_javascript技巧
最近在學習backbone,學習理解backbone就要先理解spa,理解spa就要先了解單頁應用是如何做到頁面不刷新改變url的。
相較於不同頁面的跳轉,AJAX可以說大大提高了用戶的瀏覽體驗,不用看到頁面切換之間的白屏是件很愜意的事情。但是很多早先的AJAX應用程式是不支援瀏覽器的前進後退的,這導致了用戶不管在網站裡瀏覽到何處,一旦刷新就會立刻回到起初的位置,並且用戶也無法通過瀏覽器的前進後退按鈕來實現瀏覽歷史的切換。
對於第一個問題,解決還算容易,只要用cookie或localStorage來記錄應用程式的狀態即可,刷新頁面時讀取一下這個狀態,然後發送對應ajax請求來改變頁面即可。但是第二個問題就很麻煩了,先說下現代瀏覽器的解決方案。
HTML5 解
要了解HTML5如何實現前進後退,就要先了解下history物件和location物件。
history物件
History 物件屬性
1.length:傳回瀏覽器歷史清單中的URL數量,使用者在目前標籤每造訪一個頁面,此數量加1。因為隱私原因,URL具體內容不可見。
2.state:與目前網址相關的對象,只能透過pushState和replaceState添加或修改。我們可以用它來儲存跟url有關的資訊。
History 物件方法
1.history.back()
此方法無參數,觸發後會返回前一個瀏覽的頁面,相當於點擊了瀏覽器的後退按鈕。
2.history.forward()
此方法無參數,觸發後會返回後退前瀏覽的頁面,相當於點擊了瀏覽器的前進按鈕。
3.history.go(number)
此方法接受一個整形變數參數,history.go(-1)相當於後退一頁,history.go(1)相當於前進一頁,history.go(0)會刷新目前頁面。
4.history.pushState(state, title, url)
改變url且不刷新頁面的關鍵就是它了,此方法會改變當前頁面的location.href並且修改當前的history.state對象,執行後history.length會增加1。此方法接受三個參數,
1.state:目前網址相關的物件。
2.title:頁面標題,但是所有瀏覽器都忽略它,要改變標題還是要用document.title。
3.url:一個與目前頁面同網域的網址,location.href會變成此值。
5.history.replaceState(state, title, url)
此方法同上,但是它不會改變history.length,只會修改當history.state和location.href。
注意pushState和replaceState第三個參數不可跨域,且不會觸發瀏覽器的popstate事件和onhashchange事件(chrome33下測試)。
location物件
除了點擊前進/後退按鈕和history事件,還可以透過location的方法和修改location的屬性來改變Url:
location物件的屬性(讀寫):
1.host:網域名稱 埠號
2.hostname:網域
3.port:埠號
4.protocol:協議
5.href:完整路徑
6.origin:協定 網域 埠
7.hash:井號 (#) 開始的 URL(hash)
8.pathname:文檔路徑 文件名稱
9.search:(?)後面的內容
可以透過改變location.href或location.hash來達到無刷新的目的。
location物件的方法:
1.assign:改變url的值,並且將目前的url加入歷史記錄中history.length會增加1。 location.assig(‘#' x)會改變url但是不刷新頁面。
2.reload:刷新頁面。
3.replace:改變url的值,但是history.length不變。使用方法同assign。
popstate事件
當url改變時,例如使用者點擊前進/後退按鈕,history.go(n)(n不等於0),location.hash = x(x不等於當前的location.hash)都會觸發此事件。可以用它來監聽url,來實現各種功能。
window.onpopstate = function(){
//do sth
}
onhashchange事件
改變hash值會觸發popstate事件,而觸發popstate事件不一定會觸發onhashchange事件。經過測試:
1.hash改變但是location.pathname不變會觸發onhashchange事件,如history.pushState(”, ”, ‘#abc');
2.hash和location.pathname一起改變則不觸發,例如history.pushState(”, ”, ‘a#abc');
老舊瀏覽器的寫法
老舊瀏覽器也不支援pushState和replaceState,所以透過popstate(事實上也不支援這個方法)監聽url變化的路走不通。那麼只能透過改變url#後面的內容來達到無刷新,但是它們又不支援onhashchange,所以對url的變化是無動於衷的(除了頁面會滾動至頁面對應id的位置)。那就只能祭出一個大招:輪詢,拿一個setInterval來監聽url的值。 Like this:
var prevHash = window.location.hash;
var callback = function(){...}
window.setInterval(function() {
if (window.location.hash != prevHash) {
prevHash = window.location.hash;
callback(prevHash);
}
}, 100);
當然這樣寫非常非常挫,如果不考慮點擊頁面帶有id的a標籤來改變hash的情況,可以利用設計模式來優雅的實現監聽url。例如經典的觀察者模式,專門用一個類別來實現改變hash的功能,然後所有要監聽url變化的類別(觀察者)去訂閱這個(被觀察者)類別。
//改變url的類別
function UrlChanger() {
var _this = this;
this.observers = [];
//新增觀察者
this.addObserver = function(obj) {...}
//刪除觀察者
this.deleteObserver = function(obj) {...}
//通知觀察者
this._notifyObservers = function() {
var length = _this.observers.length;
console.log(length)
for(var i = 0; i _this.observers[i].update();
}
}
//改變url
this.changeUrl = function(hash) {
window.location.hash = hash;
_this._notifyObservers();
}
}
//監聽類別
function oneOfObservers() {
var _this = this;
this.update = function() {...}
}
//實作
var o1 = new UrlChanger();
var o2 = new oneOfObservers();
o1.addObserver(o2);
o1.changeUrl('fun/arg1/arg2/');
//o2 has do sth...

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在網頁中使用本地安裝的字體文件最近,我從網上下載了一種免費字體,並成功將其安裝到了我的系統中。現在...

如何使用JavaScript或CSS控制瀏覽器打印設置中的頁首和頁尾在瀏覽器的打印設置中,有一個選項可以控制是否顯�...

CSS中如何實現水平選項的水平滾動效果?在現代網頁設計中,如何實現類似於水平選項卡的效果,並且支持鼠標...

如何在自適應設計中解決高度調整難題?在自適應設計中,高度調整往往是一個棘手的問題。特別是在處理類似...

Apache服務器是強大的Web服務器軟件,充當瀏覽器與網站服務器間的橋樑。 1. 它處理HTTP請求,根據請求返回網頁內容;2. 模塊化設計允許擴展功能,例如支持SSL加密和動態網頁;3. 配置文件(如虛擬主機配置)需謹慎設置,避免安全漏洞,並需優化性能參數,例如線程數和超時時間,才能構建高性能、安全的Web應用。
