学习笔记:location.hash和history.pushState()

在浏览器中改变地址栏url,将会触发页面资源的从新加载,这使得咱们能够在不一样的页面间进行跳转,得以浏览不一样的内容。但随着单页应用的增多,愈来愈多的网站采用ajax来加载资源。由于异步加载的特性,地址栏上的资源路径没有被改变,随之而来的问题就是页面的状态没法被保存。这致使咱们难以经过熟悉的方式(点击浏览器前进/后退按钮),在先后的页面状态间进行切换。html

为了解决ajax页面状态不能返回的问题,人们想出了一些曲线救国的方法,好比利用浏览器hash的特性,将新的资源路径假装成锚点,经过onhashchange事件来改变状态,同时又避免了浏览器刷新。但这样始终显得有些hack。ajax

如今HTML5规范为 window.history引入了两个新api,pushState 和 replaceState,咱们可使用它很方便的达到改变url不重载页面的目的api

——引用于https://blog.csdn.net/helloxiaoliang/article/details/73850428浏览器

location.hashlocation服务器

当一个页面的(显示)状态被改变时,能够经过location.hash实现刷新页面后或者copy页面的URL再打开后保持状态而不还原。session

当hash只有一个#时,location.hash返回空字符串;当hash不止一个#时,location.hash返回#以及#后面的部分。异步

当 一个window的 hash (URL 中 # 以及#后面的部分,可经过location.hash返回)改变时就会触发 hashchange 事件。网站

window.location属性返回一个有文档的当前位置的信息的Location对象。google

语法:var oldLocation = location; location = newLocation;url

不管何时,当一个新值被赋予location对象,一个文档将经过这个URL被加载,就像是location.assign()被这个URL调用了同样。

location.reload(true);:强制从服务器从新加载当前页面。

location.replace('http://example.com/#' + location.pathname);:将经过使用replace()方法插入location.pathname的值进hash来从新加载页面。注意,这replace()方法和字符串的replace()方法不是一个东西。

location.search = sData;:经过改变search属性来发送一个字符串数据给服务器。"?Some%20data"添加到当前的URL,而后URL被送到服务器(若是服务器没有采起动做,当前文档就用这个改变的search字符串从新加载)。

操纵浏览器历史

DOM window 对象经过 history 对象提供了对浏览器历史的访问。

window.history.back();:和用户点击浏览器回退按钮的效果相同。相似的还有window.history.forward();和window.history.go(Num);。另外,window.history.length; 能够得到历史堆栈中页面的数量。执行history.back()或history.forward()后会触发 window.onpopstate事件。

pushState()方法毫不会致使hashchange 事件被激活,就算新的URL和旧的只在hash上有区别。

history.pushState() 方法和history.replaceState()方法分别能够添加和改变历史实体。这两个方法要和window.onpopstate事件一块儿用。push和pop说明它们的行为就像栈。popstate事件会被触发当一个文档的激活的历史实体改变。若是激活的历史实体是由history.pushState()建立的,或者是被history.replaceState()改变过,那popstate事件的state属性(即e.state)会包含一个该激活的历史实体的sate对象的副本;若是不是,那e.state的值为null。调用history.pushState()方法和history.replaceState()方法不会触发popstate事件,the popstate event is only triggered by performing a browser action, such as clicking on the back button (or calling history.back() in JavaScript)。如今的浏览器加载页面时都不会触发popstate事件了(之前有的浏览器会)。

举个例子。history.pushState({ foo: "bar" }, "", "bar.html");会使地址栏的http://mozilla.org/foo.html变成http://mozilla.org/bar.html,可是不会使浏览器加载http://mozilla.org/bar.html,甚至都不会使浏览器检查http://mozilla.org/bar.html是否存在。假设用户在这个页面导航到了http://google.com,而后点击浏览器的回退按钮。这时,地址栏变成http://mozilla.org/bar.html,并且浏览器会加载http://mozilla.org/bar.html。若是这时你读取history.state,你会获得{ foo: "bar" }(即history.pushState()的第一个参数)。这时popstate事件不将被触发(?),由于页面是经过被加载而显示的(页面加载时触发的是load事件而不是popstate事件)。若是咱们再点击回退按钮,才会回到http://mozilla.org/foo.html,这时文档会得到一个popstate事件(能够经过这个事件改变文档内容),且history.state是null。总之,history.pushState()会添加一个历史实体并激活它(也就是如今的页面变成新添加的历史实体了),但暂时仍是显示原来的历史实体,只有当再次回到这个页面时(包括刷新,可是要注意刷新不会触发popstate事件哦,只有前进和后退会触发)才会显示新添加的历史实体。

history.pushState()接收三个参数,一个对象(用做state),一个字符串(用做标题,可是目前都被浏览器忽略),一个字符串(用做URL,是可选的):

·state会成为history.pushState()添加的历史实体的属性,能够用history.state得到。传入state的参数要能字符串化,好比能用JSON字符串化,由于火狐浏览器会把state这个对象存在用户的磁盘,以便当用户重启浏览器时state这个对象能恢复实际伤并不能恢复。state这个对象字符串化后的大小有限制(火狐是640K),若是须要更多的空间,你应该使用sessionStorage 和/或localStorage。

·第二个参数传入空的字符串便可。

·传入的URL能够是相对的也能够是绝对的。若是是相对的,它将相对于当前的URL被解析。传入的URL必须和当前的URL同源。若是不传入URL,则会被设置为当前的URL。

总之,调用pushState()和设置window.location = "#foo"(设置hash,与window.location.hash = "#foo"等效,且window.可省略)很像,二者都建立了并激活了一个新的历史实体。可是前者由如下优势:

1.         新的URL能够是任何和当前URL同源的URL,而设置window.location让你智能呆在同一个文档里,由于你只改变了hash。

2.         你能够不改变URL而建立新的历史实体,而经过设置window.location = "#foo";建立一个新的历史实体则必需要求当前的hash不是#foo。

3.         你能够在state中放入任何数据,而用hash就只能在URL末尾放入短字符串形式的数据。

history.replaceState()和history.pushState()很像,除了是改变当前的历史实体而不是建立一个新的。当你像更新当前的历史实体的state对象或URL来响应用户的行为时,replaceState()至关有用。

相关文章
相关标签/搜索