pushState的学习
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:

这个时候点击浏览器回退,神奇的一幕出现了,局部刷新的内容已经被浏览器记录下来。今天笔者的内容到此为止,写的匆忙。很多不足之处多多见谅。