前端路由
前端路由指URL与内容间的映射关系
第一种: Hash实现方式 利用锚点#
优缺点:
- 兼容性好(a标签)
- 地址中具有#,不太美观
- 前进后退功能比较繁琐
hash实现路由步骤
- 通过a标签实现 利用#锚点阻止跳转
- 通过window的hashchange监听hash值得变化
- 通过loaction.hash获取hash值,然后根据hash值实现对应的展示内容跳转
示例
<!-- dom结构-->
<div>
<a href="#/">首页</a>
<a href="#/index">index内容</a>
<a href="#/title">title内容</a>
<p>首页内容</p>
</div>
const pk = document.querySelector('p');
// 通过hashchange方法进行监听
window.onhashchange = () => {
// 获取hash值
const hash = location.hash.replace('#', '')
// console.log(hash);
switch (hash) {
case '/':
pk.innerHTML = '这是首页内容';
break;
case '/index':
pk.innerHTML = '这是index内容';
break;
case '/title':
pk.innerHTML = '这是title内容';
break;
}
}
// 封装hash
const router = {
// 存储path和处理函数
routes: [],
// 注册路由的方法
route(path, callback) {
this.routes[path] = callback;
},
// 初始化路由
init() {
// 存储this,在事件函数内部使用
const that = this;
window.onhashchange = () => {
const hash = location.hash.replace('#', '');
this.routes[hash] && this.routes[hash]();
}
}
}
// 注册路由
router.route('/', () => pk.innerHTML = '这是首页内容')
router.route('/index', () => pk.innerHTML = '这是index内容')
router.route('/title', () => pk.innerHTML = '这是title内容')
// 初始化路由 开始监听
router.init();
第二种: History方式
-
History方式采用h5提供的新功能实现前端路由
优缺点:
- 不用使用锚点#,地址中也就不会出现#
- 可以通过
history.pushState()
快速而简单的实现后退和前进功能 - 采用js的方法阻止默认事件触发
return fales/preventDefault()
History实现路由的方法:
-
通过给a标签添加点击事件,阻止在这里插入代码片默认跳转事件
-
通过
history.pushState()
方法给浏览器添加一个记录(即给地址后面添加path并且不会跳转) -
通过执行注册路由的回调函数,来改变页面展示内容
-
通过
popstate
事件来监控浏览器的前进后退功能,
history.pushState(null,null,path)
参数说明:
参数1:代表与当前路径相关的状态对象,进行历史记录检测
参数2:传入标题title内容,目前浏览器不支持
参数3:path,URL需要修改到的路径,且不会发送跳转
实例
<div>
<a href="/">首页</a>
<a href="/index">index内容</a>
<a href="/title">title内容</a>
<p>首页内容</p>
</div>
<script>
// 获取dom元素进行后续操作
const eles = document.querySelectorAll('a');
const pk = document.querySelector('p')
const router = {
routes: [],
route(path, callback) {
this.routes[path] = callback;
},
go(path) {
history.pushState({
path: path
}, null, path);
this.routes[path] && this.routes[path]();
},
// 监听前进后退功能
init() {
const that = this;
window.addEventListener('popstate', e => {
let path = e.state ? e.state.path : '/';
this.routes[path] && this.routes[path]();
})
}
}
// 注册路由
router.route('/', () => pk.innerHTML = '这是首页内容')
router.route('/index', () => pk.innerHTML = '这是index内容')
router.route('/title', () => pk.innerHTML = '这是title内容')
// 绑定go方法
eles.forEach(ele => {
ele.onclick = e => {
// 获取dom元素的path
let path = e.target.getAttribute('href')
// console.log(e.target.getAttribute('href'));
// 调用go方法
router.go(path);
return false;
}
})
// 启动监听
router.init();
</script>