window.onpopstate、window.history.pushState、window.history.replaceState、window.onpageshow 梦里梦外; 2022-12-21 03:18 151阅读 0赞 window.onpopstate、window.history.pushState、window.history.replaceState、window.onpageshow、visibilitychange **1、window.onpopstate、window.history.pushState、window.history.replaceState API的区分** window.onpageshow 控制浏览器历史记录的api——window.onpopstate(),每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发 window.history.pushState(). window.histoey.replaceState() 添加和修改历史记录条目,与window.onpopstate 配合使用 **window.onpopstate触发时机:** 1)点击浏览器的前进、后退按钮,安卓的后退按钮 2)在js中调用history.go() history.forward() history.back() 3)a标签的锚点 4)当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会 **注意:history.pushState() history.replaceState()不会触发window.onpopstate()方法** **window.history对象具有的属性**: window.history = \{ length:1, pushState: fn, replaceState: fn, scrollRestoration: ‘auto’, state: null , \_\_proto\_\_: \{ back: fn, forward: fn, go: fn, length:1, pushState: fn, replaceState: fn, scrollRestoration: ‘auto’, state: null \} \} window.history.length:表示在同一个tab,会话历史中元素数总个数 比如有a.html b.html. c.html. d.html四个页面 首次打开a.html页面,这时候history.length=1 从a.html跳到b.html,使用location.href或者this.$router.push()跳转,这时候history.length=2 从b.html跳到c.html,使用location.href或者this.$router.push()跳转,这时候history.length=3 从c.html跳到a.html,使用history.go(-2)跳转,这时候history.length=3 从a.html跳到b.html,使用location.href或者this.$router.push()跳转,这时候history.length=3 总结:也就是history.length记录了同一个tab中,栈中元素总个数 如果用新开webview的方式打开该页面,则该页面相当于在另外一个tab中,所以当前history.length = 1 history=3表示同一个tab里面有3条历史数据记录,最多向前回跳两个页面 **如果用location.href或者this.$router.push()、history.pushState()方法跳转,则会向历史记录栈中添加一条数据** **this.$router.replace()方法则不会向历史记录栈中添加数据** 注意 pushState() 绝对不会触发 hashchange 事件,即使新的URL与旧的URL仅哈希不同也是如此 history.replaceState() 的使用与 history.pushState() 非常相似,区别在于 replaceState() 是修改了当前的历史记录项而不是新建一个 $router.push()和$router.replace()都会触发window.onpopstate方法 **2、判断页面是否是后退进入,可以监听方法pageshow方法,event.persisted === true 表示后退进入,并非首次加载,同时使用window.performance && window.performance.navigation.type === 2做兼容** window.onpageshow = function (event) \{ // 判断是否是后退进入 if (event.persisted || (window.performance && window.performance.navigation.type === 2)) \{ if (router.currentRoute.path === '/order' || router.currentRoute.path === '/cartOrder' || router.currentRoute.path === '/coupon-detail' || router.currentRoute.path === '/order-detail' || router.currentRoute.path === '/exchange-order' || router.currentRoute.path === '/goods-detail') \{ window.location.reload() \} \} \} **注意:window.onpageshow方法触发的时机:第一次加载页面、前进或者后退到该页面都会触发** **3、visibilitychange事件:页面显示和隐藏的时候会触发。注意:第一次加载完成页面的时候不会触发该方法** 触发时机:当在浏览器中切换tab项,或者页面从后台唤醒(即app间的切换),这时候会触发visibilitychange事件两次:先是document.visibilityState=hidden,然后是document.visibilityState=visible 如果想在页面唤醒的时候,做一些处理,可以用该方法做监听,[https://developer.mozilla.org/zh-CN/docs/Web/API/Document/visibilitychange\_event][https_developer.mozilla.org_zh-CN_docs_Web_API_Document_visibilitychange_event] // 1、在document对象添加监听事件,不要在window对象上添加,上为了兼容safari<14的时候 // 2、回调函数要用箭头函数,这样能保持this指向不变,比如vue中,this就指向当前vue文件中的实例对象,可以访问this.$route对象等属性 // 如果回调函数是这种形式function () {},那么在回调函数中的this指向就是window对象 document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') { // do something } }) 有的时候,我们会用app提供的唤端方法做处理,但是有的时候该方法不能监听到唤端事件,这时候可以考虑用visibilitychange事件做监听处理 [https_developer.mozilla.org_zh-CN_docs_Web_API_Document_visibilitychange_event]: https://developer.mozilla.org/zh-CN/docs/Web/API/Document/visibilitychange_event
还没有评论,来说两句吧...