hash模式
使用hashchange
事件监听地址栏变化,从而更新dom.
demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!doctype html> <div class="main"> <a href="#personal">personal</a><br /> <a href="#search">search</a><br /> </div> <script> let main = document.querySelector("div.main"); window.onhashchange = (e) => { let path = e.newURL; main.innerHTML = path; }; </script>
|
history模式
- 劫持跳转事件
- 使用
history.pushState
实现更新地址栏
demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <!doctype html> <div class="main"><a href="test.html">test.html</a><br /></div> <script> let main = document.querySelector("div.main"); main.addEventListener("click", (e) => { if (e.target.nodeName === "A") { e.preventDefault(); let path = e.target.href; window.history.pushState({}, "", path); main.innerHTML = `${path}`; } }); </script>
|
history模式下,跳转并不会真的发送请求,但是改变了地址栏,此时刷新会导致404错误。
所以后端要重定向所有的请求到索引页面,以nginx为例:
1 2 3 4
| location / { # 告诉nginx找不到资源时如何处理 try_files $uri $uri/ /index.html; }
|
这样还有一个问题,跳转后刷新一个页面会导致回到首页,失去了路由的意义,所以要在页面刚加载时读取到地址栏信息,然后根据地址渲染页面。