javascript history對象詳解
前面的話
history對象保存著用戶上網(wǎng)的歷史記錄,從窗口被打開的那一刻算起。由于安全方面的考慮,開發(fā)人員無法得到用戶瀏覽器的URL,但借由用戶訪問過的頁面列表,可以在不知道實(shí)際URL的情況下實(shí)現(xiàn)后退和前進(jìn)。本文將詳細(xì)介紹BOM中的history對象
length
history.length屬性保存著歷史記錄的URL數(shù)量。初始時(shí),該值為1。如果當(dāng)前窗口先后訪問了三個(gè)網(wǎng)址,history.length屬性等于3
由于IE10+瀏覽器在初始時(shí)返回2,存在兼容性問題,所以該值并不常用
history.length // 初始時(shí),該值為1 history.length // 訪問三個(gè)網(wǎng)址后,該值為3
跳轉(zhuǎn)方法
history對象提供了一系列方法,允許在瀏覽歷史之間移動(dòng),包括go()、back()和forward()
【go()】
使用go()方法可以在用戶的歷史記錄中任意跳轉(zhuǎn)。這個(gè)方法接收一個(gè)參數(shù),表示向后或向前跳轉(zhuǎn)的頁面數(shù)的一個(gè)整數(shù)值。負(fù)數(shù)表示向后跳轉(zhuǎn)(類似于后退按鈕),正數(shù)表示向前跳轉(zhuǎn)(類似于前進(jìn)按鈕)
//后退一頁 history.go(-1) //前進(jìn)一頁 history.go(1); //前進(jìn)兩頁 history.go(2);
go()方法無參數(shù)時(shí),相當(dāng)于history.go(0),可以刷新當(dāng)前頁面
//刷新當(dāng)前頁面 history.go(); //刷新當(dāng)前頁面 history.go(0);
【back()】
back()方法用于模仿瀏覽器的后退按鈕,相當(dāng)于history.go(-1)
【forward()】
forward()方法用于模仿瀏覽器的前進(jìn)按鈕,相當(dāng)于history.go(1)
//后退一頁 history.back() //前進(jìn)一頁 history.forward()
如果移動(dòng)的位置超出了訪問歷史的邊界,以上三個(gè)方法并不報(bào)錯(cuò),而是靜默失敗
[注意]使用歷史記錄時(shí),頁面通常從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁
增改記錄
HTML5為history對象添加了兩個(gè)新方法,history.pushState()和history.replaceState(),用來在瀏覽歷史中添加和修改記錄。state屬性用來保存記錄對象,而popstate事件用來監(jiān)聽history對象的變化
[注意]IE9-瀏覽器不支持
【pushState()】
history.pushState()方法向?yàn)g覽器歷史添加了一個(gè)狀態(tài)。pushState()方法帶有三個(gè)參數(shù):一個(gè)狀態(tài)對象、一個(gè)標(biāo)題(現(xiàn)在被忽略了)以及一個(gè)可選的URL地址
history.pushState(state, title, url);
state object —— 狀態(tài)對象是一個(gè)由pushState()方法創(chuàng)建的、與歷史紀(jì)錄相關(guān)的javascript對象。當(dāng)用戶定向到一個(gè)新的狀態(tài)時(shí),會觸發(fā)popstate事件。事件的state屬性包含了歷史紀(jì)錄的state對象。如果不需要這個(gè)對象,此處可以填null
title —— 新頁面的標(biāo)題,但是所有瀏覽器目前都忽略這個(gè)值,因此這里可以填null
URL —— 這個(gè)參數(shù)提供了新歷史紀(jì)錄的地址。新URL必須和當(dāng)前URL在同一個(gè)域,否則,pushState()將丟出異常。這個(gè)參數(shù)可選,如果它沒有被特別標(biāo)注,會被設(shè)置為文檔的當(dāng)前URL
假定當(dāng)前網(wǎng)址是example.com/1.html,使用pushState方法在瀏覽記錄(history對象)中添加一個(gè)新記錄
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
添加上面這個(gè)新記錄后,瀏覽器地址欄立刻顯示example.com/2.html,但并不會跳轉(zhuǎn)到2.html,甚至也不會檢查2.html是否存在,它只是成為瀏覽歷史中的最新記錄。假如這時(shí)訪問了google.com,然后點(diǎn)擊了倒退按鈕,頁面的url將顯示2.html,但是內(nèi)容還是原來的1.html。再點(diǎn)擊一次倒退按鈕,url將顯示1.html,內(nèi)容不變
總之,pushState方法不會觸發(fā)頁面刷新,只是導(dǎo)致history對象發(fā)生變化,地址欄的顯示地址發(fā)生變化
如果pushState的url參數(shù),設(shè)置了一個(gè)新的錨點(diǎn)值(即hash),并不會觸發(fā)hashchange事件,,即使新的URL和舊的只在hash上有區(qū)別
如果設(shè)置了一個(gè)跨域網(wǎng)址,則會報(bào)錯(cuò)。這樣設(shè)計(jì)的目的是,防止惡意代碼讓用戶以為他們是在另一個(gè)網(wǎng)站上
// 報(bào)錯(cuò) history.pushState(null, null, 'https://twitter.com/hello');
【replaceState()】
history.replaceState方法的參數(shù)與pushState方法一模一樣,不同之處在于replaceState()方法會修改當(dāng)前歷史記錄條目而并非創(chuàng)建新的條目
假定當(dāng)前網(wǎng)頁是example.com/example.html
history.pushState({page: 1}, 'title 1', '?page=1');
history.pushState({page: 2}, 'title 2', '?page=2');
history.replaceState({page: 3}, 'title 3', '?page=3');
history.back()
// url顯示為http://example.com/example.html?page=1
history.back()
// url顯示為http://example.com/example.html
history.go(2)
// url顯示為http://example.com/example.html?page=3
【state】
history.state屬性返回當(dāng)前頁面的state對象
history.pushState({page: 1}, 'title 1', '?page=1');
history.state// { page: 1 }
【popstate事件】
每當(dāng)同一個(gè)文檔的瀏覽歷史(即history對象)出現(xiàn)變化時(shí),就會觸發(fā)popstate事件
需要注意的是,僅僅調(diào)用pushState方法或replaceState方法,并不會觸發(fā)該事件,只有用戶點(diǎn)擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用javascript調(diào)用back()、forward()、go()方法時(shí)才會觸發(fā)。另外,該事件只針對同一個(gè)文檔,如果瀏覽歷史的切換,導(dǎo)致加載不同的文檔,該事件也不會觸發(fā)
使用的時(shí)候,可以為popstate事件指定回調(diào)函數(shù)。這個(gè)回調(diào)函數(shù)的參數(shù)是一個(gè)event事件對象,它的state屬性指向pushState和replaceState方法為當(dāng)前URL所提供的狀態(tài)對象(即這兩個(gè)方法的第一個(gè)參數(shù))
window.onpopstate = function (event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
};
上面代碼中的event.state,就是通過pushState和replaceState方法,為當(dāng)前URL綁定的state對象
這個(gè)state對象也可以直接通過history對象讀取
var currentState = history.state;
往返緩存
默認(rèn)情況下,瀏覽器會在當(dāng)前會話(session)緩存頁面,當(dāng)用戶點(diǎn)擊“前進(jìn)”或“后退”按鈕時(shí),瀏覽器就會從緩存中加載頁面
瀏覽器有一個(gè)特性叫“往返緩存”(back-forward cache或bfcache),可以在用戶使用瀏覽器的“后退”和“前進(jìn)”按鈕時(shí)加快頁面的轉(zhuǎn)換速度。這個(gè)緩存中不僅保存著頁面數(shù)據(jù),還保存了DOM和javascript的狀態(tài);實(shí)際上是將整個(gè)頁面都保存在了內(nèi)存里。如果頁面位于bfcache中,那么再次打開該頁面時(shí)就不會觸發(fā)load事件
[注意]IE10-瀏覽器不支持
【pageshow】
pageshow事件在頁面加載時(shí)觸發(fā),包括第一次加載和從緩存加載兩種情況。如果要指定頁面每次加載(不管是不是從瀏覽器緩存)時(shí)都運(yùn)行的代碼,可以放在這個(gè)事件的監(jiān)聽函數(shù)
第一次加載時(shí),它的觸發(fā)順序排在load事件后面。從緩存加載時(shí),load事件不會觸發(fā),因?yàn)榫W(wǎng)頁在緩存中的樣子通常是load事件的監(jiān)聽函數(shù)運(yùn)行后的樣子,所以不必重復(fù)執(zhí)行。同理,如果是從緩存中加載頁面,網(wǎng)頁內(nèi)初始化的JavaScript腳本(比如DOMContentLoaded事件的監(jiān)聽函數(shù))也不會執(zhí)行
[注意]雖然這個(gè)事件的目標(biāo)是document,但必須將其事件處理程序添加到window
pageshow事件有一個(gè)persisted屬性,返回一個(gè)布爾值。頁面第一次加載時(shí)或沒有從緩存加載時(shí),這個(gè)屬性是false;當(dāng)頁面從緩存加載時(shí),這個(gè)屬性是true
(function(){
var showCount = 0;
window.onload = function(){
console.log('loaded');
}
window.onpageshow = function(e){
e = e || event;
showCount ++;
console.log(e.persisted,showCount + 'times');
}
})();
[注意]上面的例子使用了私有作用域,以防止變量showCount進(jìn)入全局作用域。如果單擊了瀏覽器的“刷新”按鈕,那么showCount的值就會被重置為0,因?yàn)轫撁嬉呀?jīng)完全重新加載了
【pagehide】
與pageshow事件對應(yīng)的是pagehide事件,該事件會在瀏覽器卸載頁面的時(shí)候觸發(fā),而且是在unload事件之前觸發(fā)。與pageshow事件一樣,pagehide在document上面觸發(fā),但其事件處理程序必須要添加到window對象
[注意]指定了onunload事件處理程序的頁面會被自動(dòng)排除在bfcache之外,即使事件處理程序是空的。原因在于,onunload最常用于撤銷在onload中所執(zhí)行的操作,而跳過onload后再次顯示頁面很可能就會導(dǎo)致頁面不正常
pagehide事件的event對象也包含persisted屬性,不過其用途稍有不同。如果頁面是從bfcache中加載的,那么persisted的值就是true;如果頁面在卸載之后會被保存在bfcache中,那么persisted的值也會被設(shè)置為true。因此,當(dāng)?shù)谝淮斡|發(fā)pageshow時(shí),persisted的值一定是false,而在第一次觸發(fā)pagehide時(shí),persisted就會變成true(除非頁面不會被保存在bfcache中)
window.onpagehide = function(e){
e = e || event;
console.log(e.persisted);
}
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時(shí)也希望多多支持腳本之家!
相關(guān)文章
深入理解JavaScript系列(26):設(shè)計(jì)模式之構(gòu)造函數(shù)模式詳解
這篇文章主要介紹了深入理解JavaScript系列(26):設(shè)計(jì)模式之構(gòu)造函數(shù)模式詳解,本文講解了基本用法、構(gòu)造函數(shù)與原型、只能用new嗎?、強(qiáng)制使用new、原始包裝函數(shù)等內(nèi)容,需要的朋友可以參考下2015-03-03
Vue2.0+ElementUI實(shí)現(xiàn)表格翻頁的實(shí)例
下面小編就為大家?guī)硪黄猇ue2.0+ElementUI實(shí)現(xiàn)表格翻頁的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
解決前后端交互數(shù)據(jù)出現(xiàn)精度丟失的多種方式
這篇文章主要為大家介紹了解決前后端交互數(shù)據(jù)出現(xiàn)精度丟失的多種方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
原生js和jQuery隨意改變div屬性style的名稱和值
用原生js和jQuery實(shí)現(xiàn)改變隨意改變div屬性style的名稱和值的結(jié)果,這個(gè)實(shí)例比較實(shí)用,新手朋友們可以看看2014-10-10
微信小程序?qū)崿F(xiàn)登錄頁云層漂浮的動(dòng)畫效果
微信小程序目前的火熱程度相信不用多言,最近利用空余時(shí)間用小程序?qū)崿F(xiàn)了個(gè)動(dòng)態(tài)的登錄頁效果,所以下面這篇文章主要給大家介紹了利用微信小程序?qū)崿F(xiàn)登錄頁云層漂浮動(dòng)畫效果的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-05-05
JavaScript實(shí)現(xiàn)文本相似度對比
這篇文章主要介紹了JavaScript實(shí)現(xiàn)文本相似度對比,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-06-06
總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips
這篇文章主要介紹了總結(jié)分享10個(gè)JavaScript代碼優(yōu)化小tips,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
js window.addEventListener實(shí)際案例
window.addEventListener 是 JavaScript 中的一個(gè)方法,用于向指定對象添加事件監(jiān)聽器,下面通過本文給大家介紹js window.addEventListener的實(shí)際案例,感興趣的朋友跟隨小編一起看看吧2024-12-12

