jquery导航吸顶+锚点定位

一、思路

当屏幕滚动到一定高度时,tab显示并且固定到顶部,当小于这个高度时,tab不显示。当切换tab时,tab对应的内容滚到顶部,这里不用锚点定位通过点击事件实现内容滚动。同样,当tab对应的内容滚到顶部时,对应的tab选中。不用锚点定位,文章底部有解释。

二、代码部分

html:

<div>
            <div class="top">上面的内容</div>
            <!-- tab 最初为隐藏状态,当tab1的内容快到达屏幕顶部时才显示 -->
            <nav class="nav-wrap hide">
                <div class="nav-hide"></div>
                <ul class="nav-ul flex">
                    <li class="active">
                        <a data-href="#tab1">tab1</a>
                    </li>
                    <li>
                        <a data-href="#tab2">tab2</a>
                    </li>
                    <li>
                        <a data-href="#tab3">tab3</a>
                    </li>
                </ul>
            </nav>
            <!-- tab对应的内容 -->
            <ul class="content">
                <li id="tab1">
                    <h3>tab1的内容</h3>
                </li>
                <li id="tab2">
                    <h3>tab2的内容</h3>
                </li>
                <li id="tab3">
                    <h3>tab3的内容</h3>
                </li> 
            </ul>
            <div class="bottom-con">下面的内容</div>
        </div>

css:

*{
    margin: 0;
    padding: 0
}
:root{
    --main-color: #FF4A51;
}
html,
body{
    color: #333;
}
a{
    text-decoration: none;
    color: #333;
}
li{
    list-style: none;
}
.hide{
    width: 100%;
    height: 60px;
    display: none;
}
.flex{
    display: flex;
    align-items: center;
}
.top{
    width: 100%;
    height: 400px;
    background: #6EBCE2;
    color: #fff;
}
#tab1,
#tab2,
#tab3{
    height: 300px;
}
.nav-wrap,
.nav-wrap ul{
    width: 100%;
    height: 60px;
    background: #fff;
}
.nav-wrap.nav-fixed{
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}
.nav-ul li{
    flex: 1;
    text-align: center;
    height: 60px;
    line-height: 60px;
}
.nav-ul li a::after{
    content: '';
    width: 16px;
    height: 2px;
    background: #fff;
    display: block;
    margin: -20px auto 0;
}
.nav-ul li.active a{
    color: var(--main-color);
}
.nav-ul li.active a::after{
    content: '';
    width: 16px;
    height: 2px;
    background: var(--main-color);
    display: block;
}
.bottom-con{
    height: 600px;
    background: violet;
    color: #fff;
}

js:

//不要忘了引入jquery
<script src="js/jquery-1.11.3.min.js"></script>
<script>
            $(function(){
                let tabHeight = '',
                    tabItem = [],
                    scrollItemId = [];
                tabHeight = $(".nav-wrap").height();//获取tab的高度
                //获取每个tab
                $('ul.nav-ul li').each(function(){
                    tabItem.push($(this))
                })
                //获取每个tab对应的内容
                $('ul.content li').each(function(){
                    scrollItemId.push($(this))
                })
                //on里面的参数:第一个:事件的类型;第二个:对谁做;第三个:执行这个事件的对象
                $('ul.nav-ul').on('click', 'li', function(){
                    $(this).addClass('active').siblings().removeClass('active');
                    // attr()方法设置或返回被选中元素的属性或者值
                    // $(selector).attr(attribute) //返回属性的值
                    // $(selector).attr(attribute, value) 设置属性和值
                    // 获取当前点击tab对应的内容的高度
                    let currItem = $(this).children('a').data('href'),
                        currItemOffset = $(currItem).offset().top;
                    //改变滚动条的高度
                        $('html, body').animate({
                          scrollTop: currItemOffset - tabHeight
                        }, 300);
                })
                let tab1Top = $("#tab1").offset().top;
                // 显示隐藏固定在顶部的tab
                $(window).scroll(function(){
                    let scrollTop = $(this).scrollTop();
                    //滚动距离到达+tab的高度大于等于tab1内容距离顶部的距离时就显示导航,否则就不显示
                    // 为了不让tab固定显示时tab1的内容被遮挡,这里当tab1滚动到距离顶部还有tab的高度时,显示tab,下面的scrollTop + tabHeight同理
                    if(scrollTop + tabHeight >= tab1Top){
                        $('.nav-wrap').removeClass("hide").addClass("nav-fixed")
                    }else{
                        $('.nav-wrap').addClass("hide")
                    }
                    scrollSpy(scrollTop)
                })
                //当屏幕滚动时,监听tab对应的内容
                function scrollSpy(scrollTop){
                    let len = scrollItemId.length;
                    for(let i = 0; i < len; i++){
                        let item = scrollItemId[i];
                        //滚动的距离+60等于tabItem中的某个li的offsetTop时,切换active
                        if(scrollTop + tabHeight >= item.offset().top){
                            tabItem[i].addClass("active").siblings().removeClass('active')
                        }
                    }
                    
                }
                
            })
            
        </script>

 不用锚点定位的原因:内容正常滚动到下面的内容的话,这时tab3会选中,但这时下面还有锚点定位的话,点击之后tab3仍然会选中而不是tab1。

posted @ 2021-01-16 20:47  狗和鹦鹉还有小花  阅读(659)  评论(0)    收藏  举报