天天看點

html模闆顯示曆史記錄,Html5使用history對象history.pushState()和history.replaceState()方法添加和修改浏覽曆史記錄...

原文:https://www.studyscript.com/Post/index/id/3018.html?page=3javascript

正文~html

概述java

浏覽器視窗有一個history對象,用來儲存浏覽曆史。web

若是目前視窗前後通路了三個網址,那麼history對象就包括三項,history.length屬性等于3。api

history.length // 3跨域

history對象提供了一系列方法,容許在浏覽曆史之間移動。數組

back():移動到上一個通路頁面,等同于浏覽器的後退鍵。浏覽器

forward():移動到下一個通路頁面,等同于浏覽器的前進鍵。緩存

go():接受一個整數做為參數,移動到該整數指定的頁面,好比go(1)至關于forward(),go(-1)至關于back()。伺服器

history.back();

history.forward();

history.go(-2);

若是移動的位置超出了通路曆史的邊界,以上三個方法并不報錯,而是默默的失敗。

history.go(0)至關于重新整理目前頁面。

history.go(0);

常見的“傳回上一頁”連接配接,代碼以下。

document.getElementById('backLink').onclick = function () {

window.history.back();

}

注意,傳回上一頁時,頁面一般是從浏覽器緩存之中加載,而不是從新要求伺服器發送新的網頁。

history.pushState()

HTML5為history對象添加了兩個新方法,history.pushState()和history.replaceState(),用來在浏覽曆史中添加和修改記錄。

if (!!(window.history && history.pushState)){

// 支援History API

} else {

// 不支援

}

上面代碼能夠用來檢查,目前浏覽器是否支援History API。若是不支援的話,能夠考慮使用Polyfill庫History.js。

history.pushState方法接受三個參數,依次為:

state:一個與指定網址相關的狀态對象,popstate事件觸發時,該對象會傳入回調函數。若是不須要這個對象,此處能夠填null。

title:新頁面的标題,可是全部浏覽器目前都忽略這個值,是以這裡能夠填null。

url:新的網址,必須與目前頁面處在同一個域。浏覽器的位址欄将顯示這個網址。

假定目前網址是example.com/1.html,咱們使用pushState方法在浏覽記錄(history對象)中添加一個新記錄。

var stateObj = { foo: 'bar' };

history.pushState(stateObj, 'page 2', '2.html');

添加上面這個新記錄後,浏覽器位址欄馬上顯示example.com/2.html,但并不會跳轉到2.html,甚至也不會檢查2.html是否存在,它隻是成為浏覽曆史中的最新記錄。假定這時你通路了google.com,而後點選了倒退按鈕,頁面的url将顯示2.html,可是内容仍是原來的1.html。你再點選一次倒退按鈕,url将顯示1.html,内容不變。

總之,pushState方法不會觸發頁面重新整理,隻是緻使history對象發生變化,位址欄會有反應。

若是pushState的url參數,設定了一個新的錨點值(即hash),并不會觸發hashchange事件。若是設定了一個跨域網址,則會報錯。

// 報錯

history.pushState(null, null, 'https://twitter.com/hello');

上面代碼中,pushState想要插入一個跨域的網址,緻使報錯。這樣設計的目的是,防止惡意代碼讓使用者覺得他們是在另外一個網站上。

history.replaceState()

history.replaceState方法的參數與pushState方法如出一轍,差別是它修改浏覽曆史中目前紀錄。

假定目前網頁是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屬性

history.state屬性傳回目前頁面的state對象。

history.pushState({page: 1}, 'title 1', '?page=1');

history.state

// { page: 1 }

popstate事件

每當同一個文檔的浏覽曆史(即history對象)出現變化時,就會觸發popstate事件。

須要注意的是,僅僅調用pushState方法或replaceState方法 ,并不會觸發該事件,隻有使用者點選浏覽器倒退按鈕和前進按鈕,或者使用JavaScript調用back、forward、go方法時才會觸發。另外,該事件隻針對同一個文檔,若是浏覽曆史的切換,緻使加載不一樣的文檔,該事件也不會觸發。

使用的時候,能夠為popstate事件指定回調函數。這個回調函數的參數是一個event事件對象,它的state屬性指向pushState和replaceState方法為目前URL所提供的狀态對象(即這兩個方法的第一個參數)。

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,就是經過pushState和replaceState方法,為目前URL綁定的state對象。

這個state對象也能夠直接經過history對象讀取。

var currentState = history.state;

注意,頁面第一次加載的時候,在load事件發生後,Chrome和Safari浏覽器(Webkit核心)會觸發popstate事件,而Firefox和IE浏覽器不會。

URLSearchParams API

URLSearchParams API用于處理URL之中的查詢字元串,即問号以後的部分。沒有部署這個API的浏覽器,能夠用url-search-params這個墊片庫。

var paramsString = 'q=URLUtils.searchParams&topic=api';

var searchParams = new URLSearchParams(paramsString);

URLSearchParams有如下方法,用來操做某個參數。

has():傳回一個布爾值,表示是否具備某個參數

get():傳回指定參數的第一個值

getAll():傳回一個數組,成員是指定參數的全部值

set():設定指定參數

delete():删除指定參數

append():在查詢字元串之中,追加一個鍵值對

toString():傳回整個查詢字元串

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還有三個方法,用來周遊全部參數。

keys():周遊全部參數名

values():周遊全部參數值

entries():周遊全部參數的鍵值對

上面三個方法傳回的都是Iterator對象。

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執行個體自己就是Iterator對象,與entries方法傳回值相同。是以,能夠寫成下面的樣子。

for (var p of searchParams) {

console.log(p);

}

下面是一個替換目前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執行個體能夠看成POST資料發送,全部資料都會URL編碼。

let params = new URLSearchParams();

params.append('api_key', '1234567890');

fetch('https://example.com/api', {

method: 'POST',

body: params

}).then(...)

DOM的a元素節點的searchParams屬性,就是一個URLSearchParams執行個體。

var a = document.createElement('a');

a.href = 'https://example.com?filter=api';

a.searchParams.get('filter') // "api"

URLSearchParams還能夠與URL接口結合使用。

var url = new URL(location);

var foo = url.searchParams.get('foo') || 'somedefault';