一、 hash模式
1、认识window.location
表示其链接到的对象的位置(URL)。在控制台打印window.location,可以看到有以下的属性和方法
2、hash在页面中有什么作用
●锚点定位<script type="text/javascript">function showNode (oNode) {var nLeft = 0, nTop = 0;for (var oItNode = oNode; oItNode; nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent);window.scrollTo(nLeft, nTop);}function showBookmark (sBookmark, bUseHash) {if (arguments.length === 1 || bUseHash) {window.location.hash = sBookmark;return;}var oBookmark = document.querySelector(sBookmark);if (oBookmark) { showNode(oBookmark); }}</script><script type="text/javascript"> function showNode (oNode) { var nLeft = 0, nTop = 0; for (var oItNode = oNode; oItNode; nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent); window.scrollTo(nLeft, nTop); } function showBookmark (sBookmark, bUseHash) { if (arguments.length === 1 || bUseHash) { window.location.hash = sBookmark; return; } var oBookmark = document.querySelector(sBookmark); if (oBookmark) { showNode(oBookmark); } } </script><script type="text/javascript"> function showNode (oNode) { var nLeft = 0, nTop = 0; for (var oItNode = oNode; oItNode; nLeft += oItNode.offsetLeft, nTop += oItNode.offsetTop, oItNode = oItNode.offsetParent); window.scrollTo(nLeft, nTop); } function showBookmark (sBookmark, bUseHash) { if (arguments.length === 1 || bUseHash) { window.location.hash = sBookmark; return; } var oBookmark = document.querySelector(sBookmark); if (oBookmark) { showNode(oBookmark); } } </script>
通过以上代码,可以实现在同一个文档下,可以通过点击到达对应的书签处,那我们怎么知道当前处在哪个书签呢?可以将该书签作为一个URL的hash。 同样的场景,其实通过a标签也能实现<p id="myBookmark1"><span class="intLink" onclick="showBookmark('#myBookmark2');">Go to bookmark #2</span></p>...<p id="myBookmark2"><span class="intLink" onclick="showBookmark('#myBookmark1');">Go to bookmark #1</span></p><p id="myBookmark1"> <span class="intLink" onclick="showBookmark('#myBookmark2');"> Go to bookmark #2 </span> </p> ... <p id="myBookmark2"> <span class="intLink" onclick="showBookmark('#myBookmark1');"> Go to bookmark #1 </span> </p><p id="myBookmark1"> <span class="intLink" onclick="showBookmark('#myBookmark2');"> Go to bookmark #2 </span> </p> ... <p id="myBookmark2"> <span class="intLink" onclick="showBookmark('#myBookmark1');"> Go to bookmark #1 </span> </p>
你会发现:在同一个文档下,指定到某一块元素,URL的hash是会变化的,但是不会对页面重新发起请求<nav><ul><li><a href="#md01"> 跳转到锚点1</a></li><li><a href="#md02"> 跳转到锚点2</a></li></ul></nav><main><ul><li id="md01">锚点一</li><li id="md02">锚点二</li></ul></main><nav> <ul> <li> <a href="#md01"> 跳转到锚点1</a> </li> <li> <a href="#md02"> 跳转到锚点2</a> </li> </ul> </nav> <main> <ul> <li id="md01"> 锚点一 </li> <li id="md02"> 锚点二 </li> </ul> </main><nav> <ul> <li> <a href="#md01"> 跳转到锚点1</a> </li> <li> <a href="#md02"> 跳转到锚点2</a> </li> </ul> </nav> <main> <ul> <li id="md01"> 锚点一 </li> <li id="md02"> 锚点二 </li> </ul> </main>
3、hashchange()
当 URL 的片段标识符更改时,将触发hashchange事件 (跟在#符号后面的 URL 部分,包括#符号),因此可以监听hashchange去做你想做的事情4、hash的应用 基于以上的说明,可以利用URL hash的变化不会重新发起http请求去实现页面内容的变化function locationHashChanged() {console.log('The hash has changed!')}window.onhashchange = locationHashChanged;function locationHashChanged() { console.log('The hash has changed!') } window.onhashchange = locationHashChanged;function locationHashChanged() { console.log('The hash has changed!') } window.onhashchange = locationHashChanged;
<a href="#/a">A页面</a><a href="#/b">B页面</a><div id="app"></div><script>function render() {app.innerHTML = window.location.hash}window.addEventListener('hashchange', render)</script><a href="#/a">A页面</a> <a href="#/b">B页面</a> <div id="app"></div> <script> function render() { app.innerHTML = window.location.hash } window.addEventListener('hashchange', render) </script><a href="#/a">A页面</a> <a href="#/b">B页面</a> <div id="app"></div> <script> function render() { app.innerHTML = window.location.hash } window.addEventListener('hashchange', render) </script>
二、 history模式
1、 认识window.history
获取History对象的引用,提供了操作浏览器会话历史(浏览器地址栏中访问的页面,以及当前页面中通过框架加载的页面)的接口。
2、 方法
2.1 前进、后退
此异步方法转到浏览器会话历史的上一页,与用户单击浏览器的返回按钮,等价于 history.go(-1)back()back()back()
此异步方法转到浏览器会话历史的下一页,与用户单击浏览器的前进按钮,等价于 history.go(1)forward()forward()forward()
通过当前页面的相对位置从浏览器历史记录(会话记录)异步加载页面。比如:参数为 -1 的时候为上一页,参数为 1 的时候为下一页。go()go()go()
2.2 pushState()
会在当前的 document 中创建和激活一个新的历史记录history.pushState(state, title[, url])history.pushState(state, title[, url])history.pushState(state, title[, url])
state | 是一个 JavaScript 对象,它与pushState()创建的新历史记录条目相关联,即传递给新URL的参数 |
---|---|
title | 大多数浏览器忽略,可传递空字符串应该可以防止将来对方法的更改 |
url | 非必传,如果是有传,则相对于当前 URL 进行解析。新网址必须与当前网址同源,否则会引发异常 |
2.test目录下终端执行<!DOCTYPE html><html><head><meta charset="utf-8"><title></title></head><body><a href="javascript:toA();">A页面</a><a href="javascript:toB();">B页面</a><a href="javascript:toC();">返回</a><script>Cfunction toA() {history.pushState({a: 111}, '', '/a')}Cfunction toB() {history.pushState({b: 222}, '', '/b')}function toC() {history.back()}</script></body></html><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <a href="javascript:toA();">A页面</a> <a href="javascript:toB();">B页面</a> <a href="javascript:toC();">返回</a> <script>C function toA() { history.pushState({a: 111}, '', '/a') }C function toB() { history.pushState({b: 222}, '', '/b') } function toC() { history.back() } </script> </body> </html><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <a href="javascript:toA();">A页面</a> <a href="javascript:toB();">B页面</a> <a href="javascript:toC();">返回</a> <script>C function toA() { history.pushState({a: 111}, '', '/a') }C function toB() { history.pushState({b: 222}, '', '/b') } function toC() { history.back() } </script> </body> </html>
3.test目录下终端执行npm i -g light-servernpm i -g light-servernpm i -g light-server
4.打开test.html 分别点击A页面,B页面,可以看到URL会发生以下变化 http://localhost:3000/test.html — http://localhost:3000/a — http://localhost:3000/b 每次变化后观察控制台你会发现当前页面并不会重新发起http请求 注意: 从某种程度来说,调用 pushState() 和 window.location = “#foo”基本上一样,他们都会在当前的 document 中创建和激活一个新的历史记录,但是 pushState() 有以下优势: 1. 新的 URL 可以是任何和当前 URL 同源的 URL。但是设置 window.location 只会在你只设置锚的时候才会使当前的 URL。 2. 非强制修改 URL。相反,设置 window.location = “#foo”; 仅仅会在锚的值不是 #foo 情况下创建一条新的历史记录。 3. 可以在新的历史记录中关联任何数据。window.location = “#foo”形式的操作,你只可以将所需数据写入锚的字符串中。 4. pushState()不会造成hashchange事件调用,即使新的URL和旧的URL只是锚点的不同light-server -s . --port 3000light-server -s . --port 3000light-server -s . --port 3000
2.3 replaceState()
把当前历史记录实体替换成新的记录(url有传的情况,否则保留当前记录),可以用于更新当前的 state 对象或者当前历史实体的 URL 来响应用户的的动作参数和pushState()一致 替换之后历史记录里面则不存在被替换掉的记录了,也就是对历史记录做前进,后退操作则不会定位到被替换掉的记录history.replaceState(stateObj, title[, url]);history.replaceState(stateObj, title[, url]);history.replaceState(stateObj, title[, url]);
2.4 popState()
前进后退操作会触发popState事件,而replaceState(), pushState()则不会触发。 如果当前处于激活状态的历史记录条目是由 history.pushState() 方法创建的或者是由 history.replaceState() 方法修改的,则 popstate 事件的 state 属性包含了这个历史记录条目的 state 对象的一个拷贝。<!DOCTYPE html><html><head><meta charset="utf-8"><title></title></head><body><a href="javascript:toA();">A页面</a><a href="javascript:toB();">B页面</a><a href="javascript:toC();">返回</a><div id="app"></div><script>function render(str) {app.innerHTML = window.location.pathname + str}function toA() {history.pushState({a: 111}, null, '/a')render('AAA')}function toB() {history.pushState({b: 222}, null, '/b')render('BBB')}function toC() {history.back()}window.onpopstate = function(event) {console.log(event)render('CCC')}</script></body></html><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <a href="javascript:toA();">A页面</a> <a href="javascript:toB();">B页面</a> <a href="javascript:toC();">返回</a> <div id="app"></div> <script> function render(str) { app.innerHTML = window.location.pathname + str } function toA() { history.pushState({a: 111}, null, '/a') render('AAA') } function toB() { history.pushState({b: 222}, null, '/b') render('BBB') } function toC() { history.back() } window.onpopstate = function(event) { console.log(event) render('CCC') } </script> </body> </html><!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <a href="javascript:toA();">A页面</a> <a href="javascript:toB();">B页面</a> <a href="javascript:toC();">返回</a> <div id="app"></div> <script> function render(str) { app.innerHTML = window.location.pathname + str } function toA() { history.pushState({a: 111}, null, '/a') render('AAA') } function toB() { history.pushState({b: 222}, null, '/b') render('BBB') } function toC() { history.back() } window.onpopstate = function(event) { console.log(event) render('CCC') } </script> </body> </html>
三、 hash模式和history模式的区别
1、 hash(#)的改变虽然让URL看起来不同,但是在手动刷新页面的时候,HTTP请求会自动忽略hash,请求的还是同一个URL。 2、 history模式不带有#符号,但是如果通过pushState或者replaceState改变了URL,在手动刷新的时候,HTTP请求会以当前实际的URL发送请求,这就可能出现资源路径请求404的情况,因此需要服务端做重定向。 3、 不管是hash模式还是history模式,都可以做到修改URL不重新发起HTTP页面请求感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
暂无评论内容