首先要进修一下history对象,history对象保存着用户的上网纪录,从阅读器窗口翻开的那一刻算起。出于平安的斟酌,开发人员没法得知用户阅读过的URL。不过,借由用户接见过的页面列表,一样能够在不知道现实URL的情况下完成退却与行进
一、history对象的要领
go(Stirng|number)
运用go要领能够在用户的汗青纪录中恣意跳转,能够向后也能够向前。这个要领接收一个参数,示意向后或向前跳转的页面数的一个整数值。负数示意向后跳转(相似阅读器的退却按钮),正数示意向前跳转(相似阅读器的行进按钮)。来看下例子
//退却一页
history.go(-1)
//行进一页
history.go(1)
//行进两页
history.go(2)
也能够给go()要领船体一个字符串参数,此时阅读器会跳转到汗青纪录中包括改字符串的第一个位置,能够退却也能够行进,详细要看哪个位置近来。假如汗青纪录中不包括该字符串,则什么都不做。比方:
//跳转到近来的wrox.com页面
history.go("wrox.com")
//跳转到近来的douban.cn页面
history.go("douban.cn")
back()
和forward
这两个要领能够来替代go(),模拟阅读器的退却和行进功用
back()相当于 go(-1) 退却一个页面
forward相当于go(1) 行进一个页面
注:接下来几个要领是html5新增的要领
二、html5中history新增的要领
pushState(state,title,url)
该要领的作用是 在汗青纪录中新增一条纪录,转变阅读器地址栏的url,然则,不革新页面。
pushState对象接收三个参数,
-
state
:一个与增加的纪录相关联的状况对象,重要用于popstate
事宜。该事宜触发时,该对象会传入回调函数。也就是说,阅读器会将这个对象序列化今后保留在当地,从新载入这个页面的时刻,能够拿到这个对象。假如不须要这个对象,此处能够填null
。 -
title
:新页面的题目。然则,如今一切阅读器都无视这个参数,所以这里能够填空字符串。 -
url
:新的网址,必需与当前页面处在同一个域。阅读器的地址栏将显现这个网址。
举个例子,假定当前网址是hello.com/1.html,运用puchState()要领在阅读纪录中增加一个新纪录
var stateObj={foo:'bar'}
history.pushState(starteObj,'','2.html')
增加新纪录后,阅读器的地址栏马上显现`hello.com/2.html
,但不会跳转到2.html,也不会搜检2.html是不是存在,它只是成为阅读汗青中的最新纪录。
总之,pushState()要领不会触发页面革新,只是致使history对象发作变化,地址栏会有回响反映,运用该要领后,就能够运用history.state属性读出状况对象
var stateObj={foo:'bar'}
history.pushState(starteObj,'','2.html')
history.state //=> {foo:"bar"}
注重:假如pushState的URL参数设置了一个新的hash值,并不会触发hashchange事宜。
replaceState(state,title,url)
replaceState要领的作用是替代当前的汗青纪录,其他的都与pushState()要领如出一辙。
假定当前网页是example.com/example.html
。
history.pushState({page: 1}, 'title 1', '?page=1')
// URL 显现为 http://example.com/example.html?page=1
history.pushState({page: 2}, 'title 2', '?page=2');
// URL 显现为 http://example.com/example.html?page=2
history.replaceState({page: 3}, 'title 3', '?page=3');
// URL 显现为 http://example.com/example.html?page=3
history.back()
// URL 显现为 http://example.com/example.html?page=1
history.back()
// URL 显现为 http://example.com/example.html
history.go(2)
// URL 显现为 http://example.com/example.html?page=3
三、popstate事宜
popstate事宜是
window
对象上的事宜,合营pushState()和replaceState()要领运用。当
同一个文档
(能够理解为同一个网页,不能跳转,跳转了就不是同一个网页了)的阅读汗青涌现变化时,就会触发popstate事宜。
上面我们说过,挪用pushState()
或许replaceState()
要领都邑转变当前的汗青纪录,仅仅挪用pushState()
要领或replaceState()
要领 ,并不会触发该事宜,别的一个前提是用户必需点击阅读器的倒退按钮或许行进按钮,或许运用js挪用history.back()或许history.forward()等要领。
所以,记着popstate事宜触发的前提
1. 处在同一个文档(同一个html页面)
2. 文档的阅读汗青(即history对象)发作转变
只需相符这两个前提,popstate事宜就会触发
详细例子
//index.html
<head>
<script>
window.onpopstate=function(){
alert('location '+document.location+',state '+JSON.stringify(event.state))
}
</script>
</head>
<body>
<!--第二步 -->
<button onclick="window.history.back()">退却</button>
<button onclick="window.history.forward()">行进</button>
<!--第一步 -->
<button onclick="window.history.pushState(null,'','1.html')">pushState</button>
</body>
先点击pushState按钮,在点击退却按钮,就会触发popstate事宜
再来一个例子
//index.html
<head>
<script>
window.onpopstate=function(){
alert('location '+document.location+',state '+JSON.stringify(event.state))
}
</script>
</head>
<body>
<a href="#one">#one</a>
</body>
直接点击a
标签,也能够触发popstate事宜
四、阅读器兼容性
图片来自mdn传送门
五、单页面路由道理
前端路由的实质是监听 URL 的变化,然后婚配路由划定规矩,显现响应的页面,而且不必革新。
现在单页面运用的路由就只有两种完成体式格局
- hash形式
- history形式
hash形式
www.test.com/##/就是Hash URL,当##
背面的哈希值发作变化时,不会向服务器要求数据,能够经由过程hashchange事宜来监听到URL的变化,从而举行跳转页面
网上偷来的一张图:
history形式
history形式比拟hash形式更雅观,须要用到Html5新增的几个api完成,道理以下:
继承偷图:
五、实例,运用history api完成简朴的单页面路由
在引见实例前先引见下location对象,location对象供应了与当前窗口中加载的文档有关的信息。它包括以下属性:
属性名 | 例子 | 申明 |
---|---|---|
host | www.hello.com:8080 | 返回服务器称号和端口号(假如有的话) |
hostname | www.hello.com | 返回服务器称号,不带端口号 |
href | http://www.hello.com | 返回当前加载页面的完全url |
pathname | /user/ming | 返回url中的目次 |
hash | #content | 返回url中的hash,假如没有返回空字符串 |
search | ?q=javascript | 返回Url的查询字符串,这个字符串以问号开首 |
我们在下方的示例中须要用到pathname
属性拿到接见的途径
一个简朴的history形式单页面路由完成以下:
//1. 路由划定规矩
const routes={
'/user':user, //user是引入的视图 import user from './view/user'
'/about':about
}
//2. 路由掌握类
class Router {
start() {
// 点击阅读器退却/行进按钮时会触发window.onpopstate事宜, 我们在这时候切换到响应页面
// https://developer.mozilla.org/en-US/docs/Web/Events/popstate
window.addEventListener('popstate', () => {
this.load(location.pathname)
})
// 翻开页面时加载当前页面 在单页面进口文件中要挪用start要领
this.load(location.pathname)
}
// 前去path, 变动地址栏URL, 并加载响应页面
go(path) {
// 变动地址栏URL
history.pushState({}, '', path)
// 加载页面
this.load(path)
}
// 加载path途径的页面
load(path) {
// 首页
if (path === '/') path = '/foo'
// 建立页面实例
const view = new routes[path]()
// 挪用页面要领, 把页面加载到document.body中
view.mount(document.body)
}
}
Router类的作用是掌握页面依据当前Url切换
start()
- 作用1: 监听onpopstate事宜,在阅读器行进或退却时加载响应的页面
- 作用2: 翻开页面时加载当前页面,须要在单页面的进口文件引入,并实行
go(path)
- 跳转到path对应的页面
load(path)
- 加载path途径的页面
参考链接
- 高程三 p215(history对象) p207(location对象)
- JavaScript规范参考教程-阮一峰
- interviewMap