history.pushstate,history.pushstate;什么意思
你是否对于history.pushstate和history.pushstate;什么意思感到困惑?别担心,今天小编将为您揭开这个谜团,让我们一同探索吧!
vue中通过history api拦截浏览器的前进后退按钮事件
现在 vueRouter的模式基本都是 history模式,它的实现是基于原生事件 popstate来实现的。
先看看 MDN文档对这个 api的解释:
也就是说我们点击浏览器的前进、后退按钮或者在 js中执行 history.back()、 history.forward()就会触发 popstate事件。
那这个 api和 vueRouter的 history模式有什么关系呢?
我们知道vue项目其实是个单页应用,大致结构如下:
所以我们在项目中各种跳转切换页面,都不会去请求 html资源,都是在一个 html中完成 dom切换,也就是更换 route-view标签里面的内容,但是我们却可以通过浏览器的前进后退按钮进行页面切换,实现的关键就是去监听 popstate事件,根据相关信息去更换 route-view标签里面的内容。
到这里需要再介绍一个 api, history.pushstate
同样看一下 MDN文档的介绍:
这个 api会往浏览器的历史栈添加一个状态,举个不太切当的例子:
比如现在在A页面,然后从A页面跳转到B页面,然后在B页面执行 history.pushState(),此时点击浏览器的后退按钮不会返回A页面,而还是在B页面。
两个 api的 MDN文档,推荐看一遍哦:
popstate
history.pushState
所以 vueRouter的 history模式简单来说就是监听 popstate事件,去执行切换显示 dom的事件;然后当路由切换时,执行了 history.pushState(),然后手动触发一遍切换显示 dom的事件。
现在回到标题,在 vue中如何拦截浏览器的前进后退按钮呢?最近刚好遇到一个需求,需要此功能来实现:
有一个列表组件 list:
列表页有很多数据,每条数据只展示基础信息,然后点击每条 item,要展示每条 item的详情,跳转到详情页。
这种需求非常常见,也有很多种办法实现,比如动态路由,但是如果是动态路由,那么返回列表页的时候,列表页就会刷新,在没有 keep-alive的情况。交互不太友好,我一般都是通过组件切换去实现:
列表通过 v-show显示隐藏,详情组件通过 v-if来触发初始化。但这样写又有一个问题,当显示详情页的时候,通过浏览器的后退按钮是回不到列表页的,因为他们在同个组件同个路由中,只能通用自己写的返回按钮来实现,为了考虑用户习惯的行为,就要实现在详情组件中点击后退按钮时能返回到列表页。
结合上面所说,在进入详情组件的时候,把这个行为当成进入一个新页面,所以就要往浏览器会话的历史堆栈中添加一个状态:
history.state储存了当前浏览器会话的信息,包括前进是什么状态,后退是什么状态,上面例子中我往里面添加了一个 id; history.pushState有三个参数,第一个参数就是 state,第二个参数可以忽略,第三个参数 url可选, vueRouter的切换就是通过第三个参数来指定,如果不传第三个参数,当前 url就不会改变。
当执行了上面的 goDetail方法后,就会显示详情组件。假如列表页的路由的/list,从/home路由跳转过来的,那当显示详情页的时候,点击浏览器的后退按钮,因为已经执行了 history.pushState,所以不会返回到/home路由,还是在/list路由。
那么怎么实现当在详情组件的时候,点击后退按钮隐藏详情组件,显示列表呢?
这时候就需要监听 popstate事件了,我在 history.pushState的时候,往 state中添加了一个标识, key为 id,通过判断是否有这个标识来切换组件:
当显示详情组件的时候,点击后退按钮,触发了 popstate事件, history.state回到未执行 history.pushState的状态,也就是 history.state没有 id这个标识,所以会隐藏掉详情组件;此时,再点击浏览器的前进按钮, history.state就会返回到执行了 history.pushState的状态,有 id这个标识,就会显示详情组件。
这样就显示了通过浏览器的前进后退来控制同个路由下组件的切换。
本文基于在一个组件中切换列表与某条数据的详情需求来说,对于涉及到的两个 history api还有很多理解不足的地方,如果你有更好的见解,请指教。
我是鸭子,祝你幸福。
router(History,hash)前端路由机制
前端路由机制
前端路由,顾名思义就是一个前端不同页面的状态管理器,可以不向后台发送请求而直接通过前端技术实现多个页面的效果。
前端路由机制原理及两种实现方式
一、History
History接口允许操作浏览器的曾经在标签页或者框架里访问的会话历史记录。
用户访问网页的历史记录通常会被保存在一个类似于栈对象中,即history对象:
history对象包含用户(在浏览器窗口)访问过的url
history对象是window对象的一部分,可以通过window.history属性进行访问。
基本的API用法如back、forward、go不做多解释,可以参考MDN
重点解释html5新增的API:
1、history.pushState()//在history对象中添加一条新的浏览记录
2、History.replaceState()//是替换history中的当前记录
3、history.state//是一个属性,可以得到当前页的state信息。
4、window.onpopstate//是一个事件,在点击浏览器后退按钮或js调用forward()、back()、go()时触发。
(和它相似的一个方法叫做onhashchange,onhashchange是老API,浏览器支持度高,本来是用来监
听hash变化的,但可以被利用来做客户端前进和后退事件的监听,onpopstate是专门用来监听浏览器
前进后退的,不仅可以支持hash,非hash的同源url也支持。)
history.pushState与History.replaceState的区别
history.pushState和History.replaceState都接收三个参数:即(data[,title][,url])
状态对象(state Object):一个object,与pushState方法创建的新历史记录条目关联。
一般传null
地址(url):新的历史记录条目的地址。
pushState和replaceState都会操作浏览器的历史记录,并且不会引起页面的刷新。
不同之处在与:一个新增,一个替换。
History模式是 HTML5新推出的功能,比之 Hash URL更加美观
一、hash
我们经常看到在url中出现#符号,这个在路由中出现的#,叫做hash,很多大型框架的路由系统都是由hash实现的。
上面提到一个方法onhashchange事件,用来监听hash变化,也可以被利用来做客户端前进和后退事件的监听。
history.pushstate 会刷新页面吗
HTML5为history对象添加了两个新方法,history.pushState()和 history.replaceState(),用来在浏览历史中添加和修改记录。所有主流浏览器都支持该方法(包括IE10)。
if(!!(window.history&& history.pushState)){
//支持History API
} else{
//不支持
}
上面代码可以用来检查,当前浏览器是否支持History API。如果不支持的话,可以考虑使用Polyfill库History.js。
history.pushState方法接受三个参数,依次为:
state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
history.pushstate;什么意思
你要问的应该是浏览器的history,也就是历史记录;我们都知道在页面中我们可以使用javascriptwindowhistory,后退到上一页面,但是出于安全考虑,javascripthistory不允许修改history里已有的url链接(也就是历史记录里面的页面地址),但可以使用pushState(相当于进栈意思)方法往history里增加url链接,并且提供popState事件(相当于出栈)监听从history栈里弹出url,所以我们就可以监听popState事件,进行相应操作,如下:
语法:element.addEventListener(event,function,useCapture);
参数:
element:文档节点、document、window或XMLHttpRequest
event:事件类型,如"click"或"mousedown"
function:事件触发后调用的函数或者是实现了EventListener接口
useCapture:布尔值,用于描述事件是冒泡还是捕获,参数可选,默认false(冒泡)
注意:event不要使用"on"前缀。例如,使用"click",而不是使用"onclick"
事件冒泡还是捕获?
事件传递方式有两种:冒泡、捕获、
事件传递定义了元素触发的顺序,如果你将<p>元素插入到<div>元素中,用户点击<p>元素,哪个元素的"click"事件先被触发呢?
在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:<p>元素的点击事件先触发,然后会触发<div>元素的点击事件。
在捕获中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即:<div>元素的点击事件先触发,然后再触发<p>元素的点击事件。
addEventListener()方法可以指定"useCapture"参数来设置传递类型:
addEventListener(event,function,useCapture);
默认值为false,即冒泡传递,当值为true时,事件使用捕获传递。
示例:手机端监听物理返回键
pushHistory();
functionpushHistory(){
varstate={
title:"title",//可以给null值
url:"#"//可以给null值
};
window.history.pushState(state,"title","#");
}
//监听到popState事件要执行的操作
window.addEventListener("popstate",function(e){
//该干嘛干嘛
},false);//false表示冒泡
以上是个人见解,看下能不能帮得上
文章到此结束,希望我们对于history.pushstate和history.pushstate;什么意思的问题能够给您带来一些启发和解决方案。如果您需要更多信息或者有其他问题,请随时联系我们。