路由的實現方式
1,利用監控錨點hash的變化實現前端路由思路, (參考hash.html)
是通過錨點來改變瀏覽器的URL,體現在URL後面會加上#,並且可以通過window.onhashChange來監聽這一變化,從而我們可以建立好hash值和對應回調函數的映射關係,然後可以通過點擊a標籤,實現在不刷新頁面情況下,通過ajax發送請求獲取異步數據來改變頁面的結構。- 優點—實現方式較爲簡單,有現成的hashChange來監聽路由哈希變化,兼容性較好,大部分瀏覽器支持
- 缺點—’#'不太美觀;由於Hash對於服務端來說是不可見的,所以對於SEO不友好
2,利用History具體實現前端路由思路 參考鏈接(history.html)
首先路由的切換可能由這麼幾個行爲引起,我們需要做不同的處理。-
點擊a鏈接
這種方式只需要在他的onclick事件先阻止他的默認跳轉行爲,然後獲取他的url,調用pushState/replaceState改變URL,然後根據url和回調函數的映射關係,觸發相應的動作 -
直接在腳本中調用pushState/replaceState
點擊瀏覽器的前進/後退按鈕,這裏需要用到另一個事件,onpopState, 當激活瀏覽器歷史記錄時會被觸發,注意這個事件不會被pushState/replaceState觸發,這個事件回調會可以獲取到當前路由下我們之前通過pushState/replaceState存入的信息,也可以拿到url信息,然後根據映射關係去執行回調。
history 擴展
- 後退一個記錄window.history.back() 前進一個記錄window.history.forward()
- 跳轉第n次記錄 window.history.go(n) 。 window.history.go(-1) 相等於window.history.back(),
- window.history.go(1) 相等於 window.history.forward(), window.history.go(0) 相等於 刷新
- pushState() 用於向history對象添加當前頁面的記錄,並且改變瀏覽器地址欄的URL。
- onpopstate事件,該事件在窗口歷史記錄改變時被觸發。
hash.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<header>
<a href="#/">首頁</a>
<a href="#/friend">朋友圈</a>
<a href="#/my">個人中心</a>
</header>
<div id="content">
</div>
</body>
<script>
window.onload = function(){
updateContent()
}
let contentObj = document.querySelector('#content')
window.addEventListener('hashchange',function(){
updateContent()
})
function updateContent(){
let hash = window.location.hash;
console.log(hash);
if(hash === '#/'){
contentObj.innerHTML = '首頁'
}else if(hash === '#/friend'){
contentObj.innerHTML = '朋友圈'
}else if(hash === '#/my'){
contentObj.innerHTML = '個人中心'
}
}
</script>
</html>
history.html
<!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>前端路由實現</title>
</head>
<body>
<div>
<div class="nav">
<a href="javascript:void(0)" data-path="index">首頁</a>
<a href="javascript:void(0)" data-path="news">新聞</a>
<a href="javascript:void(0)" data-path="about">關於</a>
</div>
<div id="router">
<!-- 內容加載區域 -->
</div>
</div>
<script>
(function () {
history.replaceState(null, null, ''); //最開始的狀態,採用replace直接替換
document.querySelector('#router').innerHTML = '<p>首頁</p>'
var allLinks = document.getElementsByTagName('a');
var urlArr = window.location.href.split('?');
var currentRouter = urlArr[urlArr.length - 1]
currentRouter = currentRouter ? currentRouter : 'index';
for(var i=0;i<allLinks.length;i++){
var allLinkItem = allLinks[i];
var path = allLinkItem.getAttribute('data-path');
allLinkItem.addEventListener('click', function () {
var text = this.text;
document.querySelector('#router').innerHTML = '<p>' + text + '</p>';
var url = this.getAttribute('data-path');
history.pushState(null, null, '?' + url);
// window.location.href = "http://localhost:3000/history.html?"+url;
})
if(path === currentRouter){
allLinkItem.click();
}
}
})()
</script>
</body>
</html>
參考鏈接 https://blog.csdn.net/u014298440/article/details/87467056