前端路由实现:通过onpopstate()监控浏览器前进后退数据
发布于 作者:苏南大叔 来源:程序如此灵动~苏南大叔在上一篇文字中,讲述了window.history.
对象上的pushState()
,这个函数可以在改变url
的同时,保存一些state
数据,以及一个不知道做啥的title
数据。那么,如何读取出这些保存好的state
数据呢?这就是本文中苏南大叔所讲述的内容:window.history.
对象上的popState
行为。
本文测试环境:mac
,chrome@73.0.3683.103
。
不存在popState()
方法
这个window.history.
对象上的popState
行为,是非常的不按常理出牌。所以,理解上需要大家发挥一点想象力。push
和pop
都是典型的堆栈操作,而pushState()
方法的存在,并不能推断出popState()
方法的存在。事实上,直接调用这个想象中的popState()
方法的话,就会有如下报错信息显示:
Uncaught TypeError: window.history.popState is not a function
截图如下:
存在popState
事件
但是,堆栈有push
必定有pop
,所以,苏南大叔认为:popstate
事件是必然存在的,可能就是不存在公开的popState()
方法罢了,比如:popState()
可能是个私有的方法。
苏南大叔提示您:可以通过window.onpopstate
来感知到popState
事件。
下面来引用一些官方的文字描述:
每当处于激活状态的历史记录条目发生变化时,popstate
事件就会在对应window
对象上触发. 如果当前处于激活状态的历史记录条目是由history.pushState()
方法创建,或者由history.replaceState()
方法修改过的, 则popstate
事件对象的state
属性包含了这个历史记录条目的state
对象的一个拷贝.
如何触发popState
事件
调用history.pushState()
或者history.replaceState()
不会触发popstate
事件. popstate
事件只会在浏览器某些行为下触发, 比如:
- 用户主动触发的:点击后退、前进按钮。
- 程序猿主动触发:在
JavaScript
中调用history.back()
、history.forward()
、history.go()
方法。
onpopstate
的使用姿势
在onpopstate
里面:
- 可以获得
event.state
数据,这个数据是pushState()
或者replaceState()
的第一个参数存进去的。 - 而关于第二个参数
title
,请注意:对于onpopstate
来说,不存在的数据。 - 第三个参数
url
,可以通过document.location
直接读取。
下面的是几个使用范例:
window.onpopstate = function(event) {
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
或者省略window.
字样:
onpopstate = function(event) {
alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
};
或者:
window.addEventListener("popstate", function(event) {
console.log(event);
}, false);
event
里面,该有的数据是没用,却存在着很多没用的数据。这个是有些奇怪。比如,您可以检查一下下面的对象,还是会有额外的收获的,具体的宝藏内容,大家可以自行查找:
console.log(event.currentTarget.clientInformation);
console.log(event.document);
查看当前页面的state
如果不监控onpopstate
事件,可以通过如下方法获得当前页面的state
数据:
window.history.state
相关文章
总结
本文中的popstate
和上文中的pushstate
加以组合,就是很多前端框架中的路由原理基础之一。至于popstate
字符中的大小写问题,个人建议您,还是严格按照demo
里面的写法写。这个问题,很难说清楚。有的时候ok,但是有的时候就不行来。严格的来说,js
语法是区分大小写的。
本文的popstate
和上文中的pushstate
,来自h5
范畴,所以,在苏南大叔的文章分类里面,也是归属于h5
范畴的。有些牵强对吧,不过,暂时想不出更好的分类了。哈哈。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。