历史记录API中hashchange与popstate的比较

hashchangepopstate事件都是浏览器历史记录API,二者都是HTML5中的API,相对而言popstatehashchange更为强大。注意这两种历史记录管理都受同源策略的限制,这里厘清下二者的区别以及相关应用:javascript

hashchange

hashchange事件是在浏览器URL中hash发生变化后触发的事件(事件触发后会在浏览器历史记录中添加一条记录),URL中后的内容就是hash,它的变化所触发的hashchange事件与ajax搭配最多。 按个人理解, 由于hash变化并不会向服务器发生请求,因此若是没有hashchange事件,当咱们点击浏览器前进和后退按钮时,服务器没法做出反应(由于服务器没法收到请求), 有了这个事件,就可使用js触发ajax的新请求让服务器做出响应。hashchange事件自己只是监测hash的变化,我认为目前其主要意义就是与ajax搭配使用从而使得在ajax下历史记录前进后退按钮依然有效。可使用如下简单的代码体会下:html

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>hashchange</title>
</head>
<body onhashchange="alert('Got a hashchange.');">
    <a href='#foo'>Click me foo</a>
        <a href='#bar'>Click me bar</a>
</body>
</html>

hashchange的文档mark? hashchangejava

popstate

popstate事件通常与pushState()replaceState()这两个方法搭配使用, 当用户点击浏览器的前进后退按钮时, 支持该事件的浏览器就会触发popState事件,顾名思义,该事件所pop的正是由pushState()方法所保存的状态栈,这里简单替下pushState()方法的语法,引用自MDN文档(注意该文档中特地指出了firefox对该方法实现的差别, 好比对title的忽略)?操纵浏览器的历史记录ajax

pushState(object,title,url)浏览器

  • 状态对象(state object) — 一个JavaScript对象,与用pushState()方法建立的新历史记录条目关联。不管什么时候用户导航到新建立的状态,popstate事件都会被触发,而且事件对象的state属性都包含历史记录条目的状态对象的拷贝。
    任何可序列化的对象均可以被当作状态对象。由于FireFox浏览器会把状态对象保存到用户的硬盘,这样它们就能在用户重启浏览器以后被还原,咱们强行限制状态对象的大小为640k。若是你向pushState()方法传递了一个超过该限额的状态对象,该方法会抛出异常。若是你须要存储很大的数据,建议使用sessionStorage或localStorage。安全

  • 标题(title) — FireFox浏览器目前会忽略该参数,虽然之后可能会用上。考虑到将来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也能够传入一个简短的标题,标明将要进入的状态。服务器

  • 地址(URL) — 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但以后,可能会试图加载,例如用户重启浏览器。新的URL不必定是绝对路径;若是是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,不然,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。session

每次触发popstate事件后,事件对象中state属性保存了以前经过pushState()方法压入的状态对象。在《javascript权威指南》中例22-3很生动地展现了该用法,这里将这个例子放在codepen中(点击连接打开,每次猜想数字后使用浏览器前进后退按钮观察状态恢复),一些注释我从新写了一下便于理解,可直接在codepen中查看源码:
DEMO ?基于popstate的猜数字游戏url

这里顺带提下replaceState() ,这个方法与pushState()语法相似,但它是用第一个参数(状态对象)主动替代当前状态,它并不会在浏览器历史记录中增长历史记录,这点相似于window.location.replace(url)firefox

hashchange与popstate的区别概括

  • hashchange只有在hash值改变时才能触发,而popstate在支持它的浏览器中只要按下“前进”“后退”按钮就会在Window对象上触发

  • popstate事件能够是任意同源的url下触发,也就是说它能够在example.com/page1 与example.com/page2中均可以触发,而hashchange只有在example.com/page1#hash中才能够(这点暂时是我的理解,并未实验)

  • 使用事件对象能够抽象数据,而没必要将数据变成字符串加在hash中

相关文章
相关标签/搜索