pushState已經出來很久了,今天筆者準備學習一下,了解一下其運用的背景和知識。
首先是要了解其背景,早期的瀏覽器要刷新頁面某個部分必須要刷新整個頁面,這樣就會導致改變很小的部分也要刷新整個頁面。導致資源要不斷的重新加載,效率極度低下,后來邊出現了Asynchronous Javascript And XML (簡稱ajax),這種通過在后臺與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
然而在ajax出現的一段時間后,大家突然發現ajax有個無法解決的問題,那就是無法利用瀏覽器本身提供的前進和后退按鈕進行操作。比如在頁面執行某個動作,該動作利用ajax請求到服務器獲取數據,更新了當前頁面的某些內容,這時想回到操作前的界面,用戶就會習慣點擊瀏覽器的后退按鈕,實際這里是無效的(要么頁面沒反應,要么打開一個前面打開的過的頁面),或者想收藏當前頁面(以便于重新打開時直接顯示當前的信息),也是無法做到的。
而h5的新對象history出現后,這個問題才得以解決。下面我們來看下history的性質,首先我們打印下history來看看。
筆者通過測試,發現history的length最多為50呢,back、forward、go不多說,看其單詞就知道什么意思了而pushState和replaceState等是本文想要了解的重點,也是可以實現瀏覽器前進后退來記錄頁面內容的關鍵。
首先要說的是pushState的入參一共有三個,分別是state、title、href。
state是一個由 pushState()方法創建的、與歷史紀錄相關的JS對象。當用戶定向到一個新的狀態時,會觸發popstate事件。事件的state屬性包含了歷史紀錄的state對象。
至于title,他是一個可有可無的東西,在有的瀏覽器是沒有的(如火狐),可以參的null
href則是新的瀏覽器地址。也是記錄狀態的關鍵。
下面開始上代碼:
var data = [
{
name: 'akm',
children: ['akm1', 'akm2', 'akm3']
},
{
name: 'awm',
children: ['awm1', 'awm2', 'awm3']
},
{
name: 'sks',
children: ['sks1', 'sks2', 'sks3']
},
{
name: 'm16a4',
children: ['m16a41', 'm16a42', 'm16a43']
},
{
name: 'm614',
children: ['m6141', 'm6142', 'm6143']
},
{
name: 'glasta',
children: ['glasta1', 'glasta2', 'glasta3']
}
]
function GetQueryString (name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
var r = window.location.search.substr(1).match(reg)
if (r != null) return unescape(r[2]); return null
}
main.js的內容就是如此了
下面是最重要的html內容,需要一個jquery.js
<html>
<head>
<meta charset="utf-8">
<script src='./jquery.js'></script>
<script src='./main.js'></script>
<style>
li {
cursor: pointer;
}
</style>
</head>
<body>
<div>
<ul id="parent">
</ul>
<hr>
<ul id="display">
</ul>
</div>
<script>
function load (title) {
data.forEach((e, i) => {
if (e.name === title) {
$('#parent').find('li').css('background', 'none').eq(i).css('background', 'green')
$('#display').html('')
data[i].children.forEach((e, i) => {
$('#display').append('<li>' + e + '</li>')
})
}
})
}
$(function () {
let query = GetQueryString('qiang')
let disIndex = 0
data.forEach((e, i) => {
if (e.name === query) {
disIndex = i
return $('#parent').append('<li style="background:green;">' + e.name + '</li>')
}
$('#parent').append('<li>' + e.name + '</li>')
})
$('#parent').off().on('click', function (e) {
let title = $(e.target).html()
document.title = title
window.history.pushState({ title: title }, title, window.location.href.split('?')[0] + '?qiang=' + title)
load(title)
})
data[disIndex].children.forEach((e, i) => {
$('#display').append('<li>' + e + '</li>')
})
window.addEventListener('popstate', function (e) { // 監聽
let title = e.state.title
load(title)
})
})
</script>
</body>
</html>
接下來來看看效果:
點擊過后,參數會發生改變,且選中了其他的內容,如點擊m16a4:
這個時候點擊瀏覽器回退,神奇的一幕出現了,局部刷新的內容已經被瀏覽器記錄下來。今天筆者的內容到此為止,寫的匆忙。很多不足之處多多見諒。