一 實現原理html
根據當前頁面滾動條的高度判斷當前頁面應當與導航欄中哪一個導航相關聯,並對相應的導航設置高亮樣式。瀏覽器
二 代碼解析函數
先簡單寫一個頁面頂端的導航欄:
<nav>
<ul>
<li><a class="nav active" href="#nav1">導航1</a></li>
<li><a class="nav" href="#nav2">導航2</a></li>
<li><a class="nav" href="#nav3">導航3</a></li>
<li><a class="nav" href="#nav4">導航4</a></li>
</ul>
</nav>
注意這裏第一個導航初始添加一個active類,表示首頁默認對應導航1。spa
爲每一個導航寫一個對應的正文頁面:設計
<div id="nav1" class="section">這是頁面1</div>
<div id="nav2" class="section">這是頁面2</div>
<div id="nav3" class="section">這是頁面3</div>
<div id="nav4" class="section">這是頁面4</div>3d
而後添加導航的CSS:視頻
*{margin:0px;} /*先清除瀏覽器默認外邊距*/
nav{
position:fixed;
width:100%;
z-index:999;
margin-top:0px
} /*fixed固定導航,並設置爲最高層,防止被後面的元素遮蓋。*/
nav ul{
text-align:center;
height:45px;
line-height:45px;
background:#0B0B0B;
}
nav li,nav li a{
display:inline-block;
height:100%;
text-decoration:none;
color:#fff;
}
nav li a{padding:0 10px;}
nav li{margin:0 10px;}
a:hover, .active{color:#B6B6B6;} /*爲鼠標懸浮的狀態以及當前頁面對應的導航設置不一樣的顏色*/htm
添加正文的CSS:blog
.section{height:660px;
width:100%;
margin:10px auto;
background:#F5F5F5;
padding-top:60px;
box-sizing:border-box;
border:1px solid red;
text-align:center;
} /*注意將box-sizing設爲border-box,每一個頁面的總體高度即爲原來設定的高度,後面用JS計算頁面高度時免去計算content、padding、margin的麻煩*/事件
此時樣式如圖所示:
下一步經過JS實現導航狀態的切換:
首先獲取全部的導航:
var navs=document.getElementByClassName('nav');
定義導航的切換方法,即每次經過增長一個類名active來爲其應用已經設定好的樣式,這裏有4個導航,因此須要給4個元素添加類名。
function reset(index){
for(var i=0;i<4;i++){
navs[i].className="nav"; //注意每次添加類名以前先清空以前設置的active,不然只要通過的頁面,對應的導航都是高亮狀態
}
navs[index].className += " active";
}
因爲是根據當前頁面和滾動條的高度關聯,從而利用滾動條的當前高度來判斷應該切換哪一個導航,所以要獲取兩個值:當前頁面距離文檔頂部的高度,以及當前滾動條的高度。
寫一個函數來根據id獲取單個頁面總體的高度height
function getHeight(id){
var elem=document.getElementById(id);
var height=parseInt(window.getComputedStyle(elem,null)['height']);
return height;
}
調用這個函數並累加得出每一個頁面距離文檔頂部的距離(不是窗口)。因爲總共4個導航對應4個頁面,因此只需判斷3個頁面便可。
var t1=getHeight("nav1");
var t2=t1+getHeight("nav2");
var t3=t2+getHeight("nav3");
再寫一個函數經過將當前滾輪高度和當前頁面距離文檔頂部的高度來做比較,判斷應當切換到哪一個導航。將頁面的滾動事件綁定到這個函數,實時獲取滾輪高度的值,實現導航樣式的實時切換:
window.onscroll=function changeCss(){
var t=document.documentElement.scrollTop || document.body.scrollTop; //獲取當前頁面滾動條的高度
if (t<t1){
reset(0); //當頁面還處於第一頁時,第一個導航亮起
} else if (t<t2){
reset(1); //當頁面滾動到第二頁時,第一個導航熄滅,第二個導航亮起
} else if (t<t3){
reset(2);
} else{
reset(3);
}
}
三 完整代碼
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>別踩白塊</title>
<style>
*{margin:0px;}
nav{position:fixed;width:100%;z-index:999;} /*fixed固定導航,並設置爲最高層,防止被後面的元素遮蓋。*/
nav ul{margin-top:0px;text-align:center;height:45px;line-height:45px;background:#0B0B0B;}
nav li,nav li a{display:inline-block;height:100%; text-decoration:none;color:#fff;}
nav li a{padding:0 10px;}
nav li{margin:0 10px;}
a:hover, .active{color:#B6B6B6;} /*爲鼠標懸浮的狀態以及當前頁面對應的導航設置不一樣的顏色*/
.section{height:660px;width:100%;margin:0px auto;background:#F5F5F5;padding-top:60px;box-sizing:border-box;border:1px solid red;text-align:center;}
</style>
</head>
<body>
<nav>
<ul>
<li><a class="nav active" href="#nav1">導航1</a></li>
<li><a class="nav" href="#nav2">導航2</a></li>
<li><a class="nav" href="#nav3">導航3</a></li>
<li><a class="nav" href="#nav4">導航4</a></li>
</ul>
</nav>
<div id="nav1" class="section">這是頁面1</div>
<div id="nav2" class="section">這是頁面2</div>
<div id="nav3" class="section">這是頁面3</div>
<div id="nav4" class="section">這是頁面4</div>
<script>
var navs=document.getElementsByClassName('nav');
function reset(index){
for(var i=0;i<4;i++){
navs[i].className="nav"; //注意每次添加類名以前先清空以前設置的active,不然只要通過的頁面,對應的導航都是高亮狀態
}
navs[index].className += " active";
}
function getHeight(id){
var elem=document.getElementById(id);
var height=parseInt(window.getComputedStyle(elem,null)['height']); //計算渲染後的style值
return height;
}
var t1=getHeight("nav1");
var t2=t1+getHeight("nav2");
var t3=t2+getHeight("nav3");
window.onscroll=function changeCss(){
var t=document.documentElement.scrollTop || document.body.scrollTop; //獲取當前頁面滾動條的高度
if (t<t1){
reset(0); //當頁面還處於第一頁時,第一個導航亮起
} else if (t<t2){
reset(1); //當頁面滾動到第二頁時,第一個導航熄滅,第二個導航亮起
} else if (t<t3){
reset(2);
} else{
reset(3);
}
}
</script>
</body>
</html>
這一次是本身設計本身寫的,因此沒有視頻資源。實際上用JQuery實現起來會更方便,可是用原生代碼可以瞭解底層原理,加深理解。導航高亮的實現方式還有別的方法,例如利用URL與頁面的對應關係,根據URL的變化判斷當前頁面應該對應的導航欄,可是這種方法也有必定的侷限性,並不能適用於全部場景。