Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Make navigation list with windowScroll

Among the page-listening methods, there are requirements that let us use scroll to listen to windowScroll.

For example, the content in the page is high, resulting in the scroll bar is compressed very small, so it is not convenient to use the mouse pulley to scroll, and can not accurately locate a node. At this point, you can add a navigation bar and click the navigation bar to move to the corresponding position. And you can judge which node the navigation bar corresponds to according to the position.

Here you can use the Window’s Scroll listener to do the core work.

Specific effects:


Basic Page building

Before writing the logic, you need to style a simple page, with five elements from first to five on the left. On the right is a list of navigation bars.

Here I use VUE to write, because it is an example, the page is relatively easy to build.

HTML code:

<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>
    
Copy the code

CSS code

@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;
                }
            }
        }
    }
}
Copy the code

JS base code

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]]}})Copy the code


JS logic

With the basic page style in place, it’s time to write the important logic (although this one will be easy)

In the current page layout, the height of the five elements is fixed, so it is easier to determine the height.

Window.addeventlistener listens for scrolling

window.addEventListener('scroll'.() = >{
    let top = window.pageYOffset;
    // heightList heightList
    this.heightList.map((item, index) = >{
        // Range judgment
        if (this.isRange(top, this.heightList[index]) ) {
            this.curNav = index; }})},true)
Copy the code

Here, for clarity, I’ve written a range determination method

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

The navigation bar now changes with the mouse wheel.

Then the navigation bar adds the click event, goNav

Here I use window.scrollTo, which scrolls the page to the appropriate location

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

At this point, a windowScroll navigation list is ready. But for variable heights, you need to think a little bit more.