路由
Hash路由
hash路由一个明显的标志是带有#,我们主要是通过监听url中的hash变化来进行路由跳转。
实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Hash路由</title>
</head>
<body>
<ul>
<li><a href="#/">turn yellow</a></li>
<li><a href="#/blue">turn blue</a></li>
<li><a href="#/green">turn green</a></li>
</ul>
<script>
class Routers {
constructor() {
this.routes = {}
//当前路由
this.currentUrl = ''
this.refresh = this.refresh.bind(this)
window.addEventListener('load', this.refresh, false)
window.addEventListener('hashchange', this.refresh, false);
}
route(path, callback) {
this.routes[path] = callback || function () {}
}
//刷新
refresh() {
this.currentUrl = location.hash.slice(1) || '/'
//执行Callback
this.routes[this.currentUrl]()
}
}
window.Router = new Routers();
var content = document.querySelector('body');
function changeBgColor(color) {
content.style.backgroundColor = color;
}
//定义路由
Router.route('/', function () {
//回调函数
changeBgColor('yellow');
});
Router.route('/blue', function () {
changeBgColor('blue');
});
Router.route('/green', function () {
changeBgColor('green');
});
</script>
</body>
</html>History路由
常用的API
- window.history.back(); // 后退
- window.history.forward(); // 前进
- window.history.go(-3); // 后退三个页面
history.pushState
用于在浏览历史中添加历史记录,但是并不触发跳转,此方法接受三个参数,依次为:
- state:一个与指定网址相关的状态对象,popstate事件触发时,该对象会传入回调函数。如果不需要这个对象,此处可以填null。
- title:新页面的标题,但是所有浏览器目前都忽略这个值,因此这里可以填null。
- url:新的网址,必须与当前页面处在同一个域。浏览器的地址栏将显示这个网址。
history.replaceState方法的参数与pushState方法一模一样,区别是它修改浏览历史中当前纪录,而非添加记录,同样不触发跳转。popstate事件,每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。
需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,只有用户点击浏览器倒退按钮和前进按钮,或者使用 JavaScript 调用back、forward、go方法时才会触发。
实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>History路由</title>
</head>
<body>
<ul>
<li><a href="/">turn yellow</a></li>
<li><a href="/blue">turn blue</a></li>
<li><a href="/green">turn green</a></li>
</ul>
<script>
//常用api
// window.history.back(); // 后退
// window.history.forward(); // 前进
// window.history.go(-3); // 后退三个页面
class Routers {
constructor() {
this.routes = {}
this._bindPopState()
}
//初始化
init(path) {
history.replaceState({
path
}, null, path)
}
route(path, callback) {
this.routes[path] = callback || function () {}
}
go(path) {
history.pushState({
path
}, null, path)
this.routes[path]();
}
// 监听popstate事件
_bindPopState() {
window.addEventListener('popState', e => {
const path = e.state && e.state.path;
this.routes[path] && this.routes[path]();
})
}
}
window.Router = new Routers();
Router.init(location.pathname);
const content = document.querySelector('body');
const ul = document.querySelector('ul');
function changeBgColor(color) {
content.style.backgroundColor = color;
}
Router.route('/', function () {
changeBgColor('yellow');
});
Router.route('/blue', function () {
changeBgColor('blue');
});
Router.route('/green', function () {
changeBgColor('green');
});
ul.addEventListener('click', e => {
if (e.target.tagName === 'A') {
e.preventDefault();
Router.go(e.target.getAttribute('href'));
}
});
</script>
</body>
</html>
查看15道真题和解析
