前端路由的两种模式

一、 hash模式

1、认识window.location

表示其链接到的对象的位置(URL)。在控制台打印window.location,可以看到有以下的属性和方法
前端路由的两种模式 插图1
其中window.location.hash会存有一个哈希值,这个hash是指URL中: #之后的路径地址(包含#)

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>
<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。 同样的场景,其实通过a标签也能实现
<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>
你会发现:在同一个文档下,指定到某一块元素,URL的hash是会变化的,但是不会对页面重新发起请求

3、hashchange()

当 URL 的片段标识符更改时,将触发hashchange事件 (跟在#符号后面的 URL 部分,包括#符号),因此可以监听hashchange去做你想做的事情
function locationHashChanged() {
console.log('The hash has changed!')
}
window.onhashchange = locationHashChanged;
4、hash的应用 基于以上的说明,可以利用URL hash的变化不会重新发起http请求去实现页面内容的变化
<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、 方法

2.1 前进、后退
back()
此异步方法转到浏览器会话历史的上一页,与用户单击浏览器的返回按钮,等价于 history.go(-1)
forward()
此异步方法转到浏览器会话历史的下一页,与用户单击浏览器的前进按钮,等价于 history.go(1)
go()
通过当前页面的相对位置从浏览器历史记录(会话记录)异步加载页面。比如:参数为 -1 的时候为上一页,参数为 1 的时候为下一页。
2.2 pushState()
会在当前的 document 中创建和激活一个新的历史记录
history.pushState(state, title[, url])
state 是一个 JavaScript 对象,它与pushState()创建的新历史记录条目相关联,即传递给新URL的参数
title 大多数浏览器忽略,可传递空字符串应该可以防止将来对方法的更改
url 非必传,如果是有传,则相对于当前 URL 进行解析。新网址必须与当前网址同源,否则会引发异常
参考例子: 1.新建test目录下新建test.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>
2.test目录下终端执行
npm i -g light-server
3.test目录下终端执行
light-server -s .  --port 3000
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只是锚点的不同
2.3 replaceState()
把当前历史记录实体替换成新的记录(url有传的情况,否则保留当前记录),可以用于更新当前的 state 对象或者当前历史实体的 URL 来响应用户的的动作
history.replaceState(stateObj, title[, url]);
参数和pushState()一致 替换之后历史记录里面则不存在被替换掉的记录了,也就是对历史记录做前进,后退操作则不会定位到被替换掉的记录
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>

三、 hash模式和history模式的区别

1、 hash(#)的改变虽然让URL看起来不同,但是在手动刷新页面的时候,HTTP请求会自动忽略hash,请求的还是同一个URL。 2、 history模式不带有#符号,但是如果通过pushState或者replaceState改变了URL,在手动刷新的时候,HTTP请求会以当前实际的URL发送请求,这就可能出现资源路径请求404的情况,因此需要服务端做重定向。 3、 不管是hash模式还是history模式,都可以做到修改URL不重新发起HTTP页面请求
------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容