<!DOCTYPE html>
<html lang="zh">
<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>单页面SPA应用路由原理</title>
<style type="text/css"> .api, .hash { color: blue; display: block; cursor: pointer;
}
</style>
</head>
<body>
<a class='api a'>a.html</a>
<a class='api b'>b.html</a>
<p>
</p>
<a class='hash a'>#a.html</a>
<a class='hash b'>#b.html</a>
<script type="text/javascript">
// 注册路由
// 说明:document.querySelectorAll('.api') 返回的是类数组对象NodeList,这个NodeList可以使用数组的方法forEach
// NodeList只有数组的forEach方法,其他方法map/filter等方法没有
document.querySelectorAll('.api').forEach(item => { item.addEventListener('click', (e) => { // 阻止默认事件
e.preventDefault(); let link = item.textContent; // pushState有3个参数,第一个参数是跳转url的状态信息,第二个参数是页面标题,第三个参数是跳转链接
//
window.history.pushState({ name: 'api' }, '页面标题', link ) }, false) // false 表示冒泡阶段执行
}); // 监听路由
// popstate 属于window事件
window.addEventListener('popstate', (e) => { console.log({ location: location.href, state: e.state }) }) // 注册路由
document.querySelectorAll('.hash').forEach(item => { item.addEventListener('click', (e) => { e.preventDefault(); let link = item.textContent; window.location.hash = link }, false) }); // 监听路由
// hashchange 属于window事件
window.addEventListener('hashchange', (e) => { console.log({ location: location.href, state: e.state }) }) </script>
</body>
</html>
hash和history的区别:
hash:
(1)丑
(2)hash会占用锚点功能
(3)兼容性较好
history:
(1)路由与后端无异
(2)IE10级以上
(3)需要后端支持