苏南大叔在上一篇文字中,讲述了window.history.对象上的pushState(),这个函数可以在改变url的同时,保存一些state数据,以及一个不知道做啥的title数据。那么,如何读取出这些保存好的state数据呢?这就是本文中苏南大叔所讲述的内容:window.history.对象上的popState行为。

前端路由实现:通过onpopstate()监控浏览器前进后退数据 - popstate
前端路由实现:通过onpopstate()监控浏览器前进后退数据(图3-1)

本文测试环境:mac,chrome@73.0.3683.103

不存在popState()方法

这个window.history.对象上的popState行为,是非常的不按常理出牌。所以,理解上需要大家发挥一点想象力。pushpop都是典型的堆栈操作,而pushState()方法的存在,并不能推断出popState()方法的存在。事实上,直接调用这个想象中的popState()方法的话,就会有如下报错信息显示:

Uncaught TypeError: window.history.popState is not a function

截图如下:

前端路由实现:通过onpopstate()监控浏览器前进后退数据 - popstate-undefined
前端路由实现:通过onpopstate()监控浏览器前进后退数据(图3-2)

存在popState事件

但是,堆栈有push必定有pop,所以,popstate事件是必然存在的,可能就是不存在公开的pop方法罢了,比如:可能是个私有的方法。

苏南大叔提示您:可以通过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

前端路由实现:通过onpopstate()监控浏览器前进后退数据 - window-history-state
前端路由实现:通过onpopstate()监控浏览器前进后退数据(图3-3)

相关文章

总结

本文中的popstate和上文中的pushstate加以组合,就是很多前端框架中的路由原理基础之一。至于popstate字符中的大小写问题,个人建议您,还是严格按照demo里面的写法写。这个问题,很难说清楚。有的时候ok,但是有的时候就不行来。严格的来说,js语法是区分大小写的。

本文的popstate和上文中的pushstate,来自h5范畴,所以,在苏南大叔的文章分类里面,也是归属于h5范畴的。有些牵强对吧,不过,写不出更好的分类的。哈哈。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留链接作者。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
未经许可,规模化镜像抄袭本站内容的行为,将会根据有关法律法规进行维权。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

 【源码】本文代码片段及相关软件,请点此获取

 【绝密】秘籍文章入口,仅传授于有缘之人   h5

本站的忠实读者小伙伴,正在阅读下面这些文章: