利用windowScroll制作导航列表

357 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

利用windowScroll制作导航列表

在页面监听的的方法中,有些需求会让我们使用到滚动监听windowScroll

比如页面中的内容高度较大,导致滚动条被压缩的很小,这样使用鼠标滑轮进行滚动就不太方便,并且也不能精确的定位到某一个节点。 此时可以添加一列导航条,通过点击导航条来移动到对应的位置。并且可以根据位置判断导航条对应的是哪一个节点。

这里可以使用window的scroll监听来完成核心的工作。

具体的效果:

223.gif


基础页面搭建

在逻辑编写之前,需要先搭建出简单页面的样式,在左侧是firstfive五个元素。右侧是导航栏列表。

223.gif

这里我使用了vue去进行编写,因为是个举例说明,页面的搭建也比较简单。

HTML代码:

<div id="main">
    <div class="contain">
        <div class="containLi" v-for="item in ulList" :class="item.name">
            {{ item.name }}
        </div>
    </div>

    <div class="navList">
        <div class="line"></div> 
        <div class="navUl">
            <div class="navLi" v-for="(li,index) in ulList" :class="curNav == index?'curNav':''" @click="goNav(index)">
                <div class="navLiLeftIcon"></div>
                <div class="navRightText">{{ li.name }}</div>
            </div>
        </div>
    </div>
</div>

<script src="../js/vue.min.js"></script>
    

CSS代码

@setHight: {
    First: 200px;
    Second: 400px;
    Third: 300px;
    Four: 300px;
    Five: 1200px
}

#main {
    width: 100%;
    height: 100%;
    display: flex;

    .contain {
        width: 700px;
        each(@setHight, {
            .@{key} {
                height: @value;
                border: 1px solid #333
            }
        });
        
    }
    .navList {
        margin-left: 25px;
        width: 115px;
        height: 280px;
        position: fixed;
        right: 300px;
        top: calc(50% - 140px);

        .line {
            position: relative;
            width: 2px;
            background-color: #a4cdf4;
            top: 20px;
            left: 8px;
            height: calc(100% - 40px);
        }
        .navUl {
            height: 100%;
            width: 100%;
            position: absolute;
            top: 0px;
            left: 3px;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
        }
        .navLi {
            width: 100%;
            height: 24px;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            .navLiLeftIcon {
                width: 8px;
                height: 8px;
                background-color: #a4cdf4;
                border: solid 2px transparent;
                border-radius: 50%;
                position: relative;
                top: 6px;
            }
            .navRightText {
                font-size: 14px;
                line-height: 25px;
                color: #81add7;
                width: 89px;
                height: 24px;
                padding-left: 8px;
                text-align: center;
            }
            &:hover {
                .navRightText {
                    color: #1090ff;
                }
                .navLiLeftIcon {
                    background-color: #69b7fc;
                }
            }
        }
        .curNav {
            .navLiLeftIcon {
                background-color: #ffffff;
                border: solid 2px #39a1ff;
            }
            .navRightText {
                color: #ffffff;
                background-color: #1090ff;
                border-radius: 5px;
            }
            &:hover {
                .navRightText {
                    color: #ffffff;
                }
                .navLiLeftIcon {
                    background-color: #ffffff;
                }
            }
        }
    }
}

JS基础代码

new Vue({
    el: '#main',
    data:{
        ulList: [
            { name: 'First' },
            { name: 'Second' },
            { name: 'Third' },
            { name: 'Four' },
            { name: 'Five' },
        ],
        curNav: 0,
        heightList:[
            [0, 200],
            [200, 600],
            [600, 900],
            [900, 1200],
            [1200, 1400]
        ]
    },

})


JS逻辑

基础的页面样式完成后,就要开始编写重要的逻辑了(虽然本次的比较简单)

在当前页面布局中,五个元素的高度是固定的,所以在高度判断时就比较容易。

image.png

window.addEventListener监听滚动

window.addEventListener('scroll', ()=>{
    let top = window.pageYOffset;
    // heightList高度列表
    this.heightList.map((item, index)=>{
        // 范围判断
        if (this.isRange(top, this.heightList[index]) ) {
            this.curNav = index;
        }
    })
}, true)

这里为了看起来清晰一些,我编写了一个范围判断方法

isRange(pos, arr) {
    if (pos >= arr[0] && pos < arr[1]) {
        return true;
    } else {
        return false;
    }
}

现在随着鼠标滚轮的滑动,导航条也能相应改变。

然后导航条添加点击事件,goNav

这里我使用了window.scrollTo,此方法能够让页面滚动到相应的位置

goNav(index) {
    window.scrollTo(0, this.heightList[index][0] + 5);
    this.curNav = index;
}

此时,一个利用windowScroll制作的导航列表就做好了。不过对于不定高度的,考虑的东西就需要更多一些。