W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
瀏覽器窗口有一個(gè)history
對(duì)象,用來(lái)保存瀏覽歷史。
如果當(dāng)前窗口先后訪問(wèn)了三個(gè)網(wǎng)址,那么history
對(duì)象就包括三項(xiàng),history.length
屬性等于3。
history.length // 3
history
對(duì)象提供了一系列方法,允許在瀏覽歷史之間移動(dòng)。
back()
:移動(dòng)到上一個(gè)訪問(wèn)頁(yè)面,等同于瀏覽器的后退鍵。forward()
:移動(dòng)到下一個(gè)訪問(wèn)頁(yè)面,等同于瀏覽器的前進(jìn)鍵。go()
:接受一個(gè)整數(shù)作為參數(shù),移動(dòng)到該整數(shù)指定的頁(yè)面,比如go(1)
相當(dāng)于forward()
,go(-1)
相當(dāng)于back()
。history.back();
history.forward();
history.go(-2);
如果移動(dòng)的位置超出了訪問(wèn)歷史的邊界,以上三個(gè)方法并不報(bào)錯(cuò),而是默默的失敗。
history.go(0)
相當(dāng)于刷新當(dāng)前頁(yè)面。
history.go(0);
常見(jiàn)的“返回上一頁(yè)”鏈接,代碼如下。
document.getElementById('backLink').onclick = function () {
window.history.back();
}
注意,返回上一頁(yè)時(shí),頁(yè)面通常是從瀏覽器緩存之中加載,而不是重新要求服務(wù)器發(fā)送新的網(wǎng)頁(yè)。
HTML5為history
對(duì)象添加了兩個(gè)新方法,history.pushState()
和history.replaceState()
,用來(lái)在瀏覽歷史中添加和修改記錄。
if (!!(window.history && history.pushState)){
// 支持History API
} else {
// 不支持
}
上面代碼可以用來(lái)檢查,當(dāng)前瀏覽器是否支持History API。如果不支持的話,可以考慮使用Polyfill庫(kù)History.js。
history.pushState
方法接受三個(gè)參數(shù),依次為:
state
:一個(gè)與指定網(wǎng)址相關(guān)的狀態(tài)對(duì)象,popstate
事件觸發(fā)時(shí),該對(duì)象會(huì)傳入回調(diào)函數(shù)。如果不需要這個(gè)對(duì)象,此處可以填null
。title
:新頁(yè)面的標(biāo)題,但是所有瀏覽器目前都忽略這個(gè)值,因此這里可以填null
。url
:新的網(wǎng)址,必須與當(dāng)前頁(yè)面處在同一個(gè)域。瀏覽器的地址欄將顯示這個(gè)網(wǎng)址。假定當(dāng)前網(wǎng)址是example.com/1.html
,我們使用pushState
方法在瀏覽記錄(history
對(duì)象)中添加一個(gè)新記錄。
var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');
添加上面這個(gè)新記錄后,瀏覽器地址欄立刻顯示example.com/2.html
,但并不會(huì)跳轉(zhuǎn)到2.html
,甚至也不會(huì)檢查2.html
是否存在,它只是成為瀏覽歷史中的最新記錄。這時(shí),你在地址欄輸入一個(gè)新的地址(比如訪問(wèn)google.com
),然后點(diǎn)擊了倒退按鈕,頁(yè)面的 URL 將顯示2.html
;你再點(diǎn)擊一次倒退按鈕,URL 將顯示1.html
。
總之,pushState
方法不會(huì)觸發(fā)頁(yè)面刷新,只是導(dǎo)致history
對(duì)象發(fā)生變化,地址欄會(huì)有反應(yīng)。
如果pushState
的url參數(shù),設(shè)置了一個(gè)新的錨點(diǎn)值(即hash
),并不會(huì)觸發(fā)hashchange
事件。如果設(shè)置了一個(gè)跨域網(wǎng)址,則會(huì)報(bào)錯(cuò)。
// 報(bào)錯(cuò)
history.pushState(null, null, 'https://twitter.com/hello');
上面代碼中,pushState
想要插入一個(gè)跨域的網(wǎng)址,導(dǎo)致報(bào)錯(cuò)。這樣設(shè)計(jì)的目的是,防止惡意代碼讓用戶以為他們是在另一個(gè)網(wǎng)站上。
history.replaceState
方法的參數(shù)與pushState
方法一模一樣,區(qū)別是它修改瀏覽歷史中當(dāng)前紀(jì)錄。
假定當(dāng)前網(wǎng)頁(yè)是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
history.state
屬性返回當(dāng)前頁(yè)面的state
對(duì)象。
history.pushState({page: 1}, 'title 1', '?page=1');
history.state
// { page: 1 }
每當(dāng)同一個(gè)文檔的瀏覽歷史(即history
對(duì)象)出現(xiàn)變化時(shí),就會(huì)觸發(fā)popstate
事件。
需要注意的是,僅僅調(diào)用pushState
方法或replaceState
方法 ,并不會(huì)觸發(fā)該事件,只有用戶點(diǎn)擊瀏覽器倒退按鈕和前進(jìn)按鈕,或者使用JavaScript調(diào)用back
、forward
、go
方法時(shí)才會(huì)觸發(fā)。另外,該事件只針對(duì)同一個(gè)文檔,如果瀏覽歷史的切換,導(dǎo)致加載不同的文檔,該事件也不會(huì)觸發(fā)。
使用的時(shí)候,可以為popstate
事件指定回調(diào)函數(shù)。這個(gè)回調(diào)函數(shù)的參數(shù)是一個(gè)event
事件對(duì)象,它的state
屬性指向pushState
和replaceState
方法為當(dāng)前URL所提供的狀態(tài)對(duì)象(即這兩個(gè)方法的第一個(gè)參數(shù))。
window.onpopstate = function (event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
};
// 或者
window.addEventListener('popstate', function(event) {
console.log('location: ' + document.location);
console.log('state: ' + JSON.stringify(event.state));
});
上面代碼中的event.state
,就是通過(guò)pushState
和replaceState
方法,為當(dāng)前URL綁定的state
對(duì)象。
這個(gè)state
對(duì)象也可以直接通過(guò)history
對(duì)象讀取。
var currentState = history.state;
注意,頁(yè)面第一次加載的時(shí)候,在load
事件發(fā)生后,Chrome和Safari瀏覽器(Webkit核心)會(huì)觸發(fā)popstate
事件,而Firefox和IE瀏覽器不會(huì)。
URLSearchParams API用于處理URL之中的查詢字符串,即問(wèn)號(hào)之后的部分。沒(méi)有部署這個(gè)API的瀏覽器,可以用url-search-params這個(gè)墊片庫(kù)。
var paramsString = 'q=URLUtils.searchParams&topic=api';
var searchParams = new URLSearchParams(paramsString);
URLSearchParams有以下方法,用來(lái)操作某個(gè)參數(shù)。
has()
:返回一個(gè)布爾值,表示是否具有某個(gè)參數(shù)get()
:返回指定參數(shù)的第一個(gè)值getAll()
:返回一個(gè)數(shù)組,成員是指定參數(shù)的所有值set()
:設(shè)置指定參數(shù)delete()
:刪除指定參數(shù)append()
:在查詢字符串之中,追加一個(gè)鍵值對(duì)toString()
:返回整個(gè)查詢字符串var paramsString = 'q=URLUtils.searchParams&topic=api';
var searchParams = new URLSearchParams(paramsString);
searchParams.has('topic') // true
searchParams.get('topic') // "api"
searchParams.getAll('topic') // ["api"]
searchParams.get('foo') // null,注意Firefox返回空字符串
searchParams.set('foo', 2);
searchParams.get('foo') // 2
searchParams.append('topic', 'webdev');
searchParams.toString() // "q=URLUtils.searchParams&topic=api&foo=2&topic=webdev"
searchParams.append('foo', 3);
searchParams.getAll('foo') // [2, 3]
searchParams.delete('topic');
searchParams.toString() // "q=URLUtils.searchParams&foo=2&foo=3"
URLSearchParams還有三個(gè)方法,用來(lái)遍歷所有參數(shù)。
keys()
:遍歷所有參數(shù)名values()
:遍歷所有參數(shù)值entries()
:遍歷所有參數(shù)的鍵值對(duì)上面三個(gè)方法返回的都是Iterator
對(duì)象。
var searchParams = new URLSearchParams('key1=value1&key2=value2');
for (var key of searchParams.keys()) {
console.log(key);
}
// key1
// key2
for (var value of searchParams.values()) {
console.log(value);
}
// value1
// value2
for (var pair of searchParams.entries()) {
console.log(pair[0]+ ', '+ pair[1]);
}
// key1, value1
// key2, value2
在Chrome瀏覽器之中,URLSearchParams
實(shí)例本身就是Iterator
對(duì)象,與entries
方法返回值相同。所以,可以寫(xiě)成下面的樣子。
for (var p of searchParams) {
console.log(p);
}
下面是一個(gè)替換當(dāng)前URL的例子。
// URL: https://example.com?version=1.0
var params = new URLSearchParams(location.search.slice(1));
params.set('version', 2.0);
window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?version=2.0
URLSearchParams
實(shí)例可以當(dāng)作POST數(shù)據(jù)發(fā)送,所有數(shù)據(jù)都會(huì)URL編碼。
let params = new URLSearchParams();
params.append('api_key', '1234567890');
fetch('https://example.com/api', {
method: 'POST',
body: params
}).then(...)
DOM的a
元素節(jié)點(diǎn)的searchParams
屬性,就是一個(gè)URLSearchParams
實(shí)例。
var a = document.createElement('a');
a.href = 'https://example.com?filter=api';
a.searchParams.get('filter') // "api"
URLSearchParams
還可以與URL
接口結(jié)合使用。
var url = new URL(location);
var foo = url.searchParams.get('foo') || 'somedefault';
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: