不刷新网页修改url链接(history.pushState和history.replaceState新增、替换历史记录用法介绍)、popstate玩转浏览器历史记录介绍、如何触发popstate事件、popstate事件的应用场景、history.state查看当前页面数据介绍

一、需求介绍

  最近遇到了在不刷新页面的情况下修改浏览器url链接的需求,考虑到可以通过history.pushState()解决。现在将我理解的一些内容分享一下,不对的地方欢迎大家指出。

  在使用方法前首先需要了解它的兼容性,history.pushState()存在一定的兼容性问题,可以通过 https://caniuse.com/#search=pushState 查看支持的浏览器版本。

  history.pushState(stateObject, title, url);

  history.pushState()主要是在不刷新浏览器的情况下,创建新的浏览记录并插入浏览记录队列中。

1、状态对象(stateObject)—— stateObject是一个JavaScript对象,通过pushState方法可以将stateObject内容传递到新页面中。

2、标题(title)—— 几乎没有浏览器支持该参数,但是传一个空字符串会比较安全。

3、地址(url)—— 新的历史记录条目的地址(可选,不指定的话则为文档当前URL)。

  浏览器在调用pushState()方法后不会加载该地址;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。

window.history.replaceState({}, '', `?query=${this.query}`)

  上面代码就可以在不刷新网页的情况下,更新url链接了。

  然后抽空研究了下这两个新方法,确实可以解决很多问题

(一)使用 pushState() 方法 可以控制浏览器自带的返回按钮

  有时候我们想让用户点击浏览器返回按钮时,不返回,或执行其他操作,这时,就用到history.pushState()方法。

  history.pushState(data,title,url) ,每执行一次都会增加一条历史记录

  data:要设置的history.state的值,可以是任意类型的值,可根据此值进行判断执行想要的操作。

  比如监听浏览器的前进后退事件:

window.addEventListener("popstate", function() {
    // 取出 设置好的 history.state 值,做判断
});

(二)history.replaceState() 与pushState()功能类似,除了这点:

  replaceState()是用来修改当前的历史记录(history实体),而不是创建一个新的历史记录,所以,当执行完history.replaceState()后,点击返回按钮照样会返回上一个页面。  当需要更新一个state对象或者当前history实体时,可以用replaceState()来实现。

  用法:当在a页面使用replaceState()修改了历史记录后,跳转到b页面,后退到a页面时,历史记录就是修改过的。

二、HTML5 的 popstate 玩转浏览器历史记录介绍

1、popstate用来做什么的?

  简而言之就是HTML5新增的用来控制浏览器历史记录的api。

2、过去如何操纵浏览器历史记录?

  window.history对象,该对象上包含有 length 和 state 的两个值,在它的__proto__上继承有back、forward、go等几个功能函数。

  在popstate之前,我们可以利用back、forward、go对history进行后退和前进操作。例如:history.back(); 后退一步,使用history.go(-1)也可实现后退效果。

  弊端:只能操作前进后退,但是无法控制前进后要去哪,history.length 都只会维持原来的状态。

3、popstate的怎么用?

  HTML5的新API扩展了window.history,使历史记录点更加开放了。可以存储当前历史记录点pushState、替换当前历史记录点replaceState、监听历史记录点popstate。

  pushState、replaceState两者用法差不多。

// 使用方法:
history.pushState(data,title,url);

//其中第一个参数data是给state的值;
// 第二个参数title为页面的标题,但当前所有浏览器都忽略这个参数,传个空字符串就好;
// 第三个参数url是你想要去的链接;

replaceState 用法类似,例如:history.replaceState("首页","",location.href+ "#news");

  两者区别:pushState会改变history.length,而replaceState不改变history.length

4、监听浏览器状态(popstate)变化事件

  可以理解为监听浏览器后退、前进的操作,只要后退或者前进就会触发。

5、如何触发popState事件:

(1)调用history.pushState()或者history.replaceState()不会触发popstate事件

(2)popstate事件只会在浏览器某些行为下触发, 比如:用户主动触发的:点击后退、前进按钮

(3)程序猿主动触发:在JavaScript中调用history.back()history.forward()history.go()方法.

6、使用场景重现:

(1)由于业务逻辑需要:打开我项目页面链接时,如果url中携带了指定参数,初始化进入页面的时候,就显示弹窗。

(2)页面中提供了一些其他链接的入口 banner

(3)这样如果进入页面时携带了参数,点击其中banner时,跳转到其他页面,然后点击宿主的返回按钮,一般是会取之前历史记录里的。这时回到之前页面时,还是会打开弹窗,因为页面链接里还携带着参数

(4)解决办法:使用pushState方法,无刷新改变页面url。我只需要这样做:

let lcthref=location.href.replace(/openMyPrize=true/g,"")
console.log(lcthref)
window.history.pushState("","",lcthref)

  也就是把 url 携带的参数给替换掉,这样就可以解决了。

7、查看当前页面的state

  如果不监控onpopstate事件,可以通过如下方法获得当前页面的state数据:

window.history.state

8、onpopstate 的使用姿势

  在onpopstate里面:

(1)可以获得event.state数据,这个数据是pushState()或者replaceState()的第一个参数存进去的。

(2)而关于第二个参数title,请注意:对于onpopstate来说,不存在的数据。

(3)第三个参数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);

 

posted @ 2019-10-25 18:28  古兰精  阅读(8294)  评论(0编辑  收藏  举报