那些年原生js實現的樓層跳轉


  最近做一個需求~~樓層跳轉(京東、淘寶側邊導航),由於現在項目都用框架,所以 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;
    }
}

   哈哈,命名即思維,我相信通過代碼大家可以弄的一清二楚,下面附上經典老圖(一圖勝千言)!

  以后要把這些瑣碎的知識點記錄下來,就如阮一峰老師所說的:炫耀從來不是我的動機,好奇才是,一邊學習,一邊記錄!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM