最近做一個需求~~樓層跳轉(京東、淘寶側邊導航),由於現在項目都用框架,所以 jquery是不能再用了,只好自己原生寫一個,其實實現起來很簡單,無非就是獲取到每個樓層距離文檔頂部的距離,然后通過控制滾動條來實現,麻煩的是需求在變,由於突然引出了一個錨點導航遇到了fixed,所以只好重新思考,滿足需求。
簡單的樓層跳轉樣例可以先看一下之前寫的demo(https://lewiscutey.github.io/yintai),看起來效果很好吧,下面詳解其中的坑:
1.錨點導航遇到fixed
現在布局一般都要box-sizing:border-box/content-box,所以不要再用padding-top:50px;margin-top:-50px;這種寫法了,最好直接寫一個子元素來定位,這樣既不占空間,又可以精確定位,下面是簡易的demo:
.floor { position: relative; #anchor{ position: absolute; top: -56px; width: 100%; } }
2.子元素永遠比父元素層級z-index高
大家總是習以為常的拿z-index來決定層級,當有時候就算z-index:9999!important;還是不起作用的時候,也許就是父子元素定位出了問題,這樣唯一的解決辦法就是給他們在加一個父元素,原來的父子元素現在變成了兄弟方可有效,嗚嗚,不幸中招。
3.慎用getBoundingClientRect()
大家可能對這個方法有點陌生,其實就是用來獲取dom節點對於bom的相對位置,今天要說的這個坑是當頁面中有錨點鏈接時,直接路由進來的頁面會顯示到錨點的內容區域,從而通過getBoundingClientRect()獲取到的值就會亂套,因此如果用作樓層跳轉里樓層高度獲取值時,就會失效了,所以慎用這個獲取相對位置的方法,我們一般用offsetTop來獲取dom節點對於bom的相對位置,這就要求把該dom直接作為body的子元素,經檢測方便可靠,下面是一個簡單的demo:
let flag = true; let floorHeights = []; let slideBar = document.querySelector("#slide-bar"); let floors = document.querySelectorAll(".floor"); let floorLinks = document.querySelectorAll("#slide-bar .floor-link"); for (let i = 0; i < floors.length; i++){ floorHeights.push(floors[i].offsetTop - 56); } window.onscroll = function() { let scrollTop = document.body.scrollTop||document.documentElement.scrollTop; if(scrollTop > 750){ if(flag){ flag = false; slideBar.style.bottom = '50%'; } }else{ if(!flag){ flag = true; slideBar.style.bottom = '-200%'; } } for (let i = 0; i < floorHeights.length; i++) { if(floorHeights[i] < scrollTop + 200){ for (let j = 0; j < floorHeights.length; j++) { floorLinks[j].style.opacity = 0; } floorLinks[i].style.opacity = 1; } } } window.onscroll(); for (let i = 0; i < floorLinks.length; i++) { floorLinks[i].index = i; floorLinks[i].onmouseover = function(){ for (let j = 0; j < floorLinks.length; j++) { floorLinks[j].style.opacity = 0; } this.style.opacity = 1; } floorLinks[i].onclick = function() { for (let j = 0; j < floorLinks.length-1; j++) { floorLinks[j].style.opacity = 0; } document.body.scrollTop = floorHeights[this.index]; document.documentElement.scrollTop = floorHeights[this.index]; } floorLinks[floorLinks.length-1].onclick = function() { document.body.scrollTop = 0; document.documentElement.scrollTop = 0; } }
哈哈,命名即思維,我相信通過代碼大家可以弄的一清二楚,下面附上經典老圖(一圖勝千言)!
以后要把這些瑣碎的知識點記錄下來,就如阮一峰老師所說的:炫耀從來不是我的動機,好奇才是,一邊學習,一邊記錄!