web常见特效——floor电梯导航

floor电梯导航

平时在pc端浏览一些电商网页,就会发现有这麽一样功能:

  • 当页面滚动到某一块区域,侧导航栏会让对应的那部分高亮显示,
  • 在点击侧导航的某个区域,页面也会自动滚动到这区域

就如下图所示
在这里插入图片描述
那么这个功能使用原生js如何去写,思路是怎么样的
思路:

  1. 当页面滚动到指定位置就不会在滚动,当页面小于设置的指定位置,就能继续滚动
  2. 当鼠标点击侧导航栏中元素,页面会滚动到该元素对应的那部分区域
  3. 当页面滚动到侧导航中设定好的区域,侧导航就会高亮某个元素

HTML代码
主要有两部分,导航栏和floor区域

 <div class="subnav">
       <ul>
           <li><a href="javascript:;">手机</a></li>
           <li><a href="javascript:;">电脑</a></li>
           <li><a href="javascript:;">平板</a></li>
           <li><a href="javascript:;">笔记本</a></li>
       </ul>
   </div>
   <div class="floor">
       <div class="shouji">
           <h1>
               我是手机区域
           </h1>
       </div>
       <div class="diannao">
           <h1>
               我是电脑区域
           </h1>
       </div>
       <div class="pingban">
           <h1>
               我是平板区域
           </h1>
       </div>
       <div class="bijiben">
           <h1>
               我是笔记本区域
           </h1>
       </div>
   </div>

CSS代码

<style>
       * {
           margin: 0;
           padding: 0;
       }

       body {
           position: relative;
       }

       .floor {
           width: 1200px;
           margin: auto;
       }

       .floor div {

           height: 500px;
           border: 1px solid #ccc;
           margin-bottom: 10px;
       }

       h1 {
           text-align: center;
       }

       .subnav {
           position: absolute;
           top: 800px;
           left: 50%;
           margin-left: 650px;
       }

       .subnav ul li {
           list-style: none;
           width: 70px;
           height: 70px;
           border: 1px solid #ccc;
           text-align: center;
           line-height: 70px;

       }

       footer {
           width: 1200px;
           margin: auto;
           height: 500px;
           background-color: #ccc;
           border: 1px solid #ccc;
           margin-bottom: 10px;
       }
   </style>

javascript代码

 <script>
        var subnav = document.querySelector('.subnav');
        var li = document.querySelectorAll('.subnav li');
        var floor = document.querySelector('.floor');
        var diannao = document.querySelector('.diannao');

        //1.如果页面滚动到电脑区域就让subnav固定到当前位置,否则就还是相对定位
        var diannaoTop = diannao.offsetTop;
        var subnavTop = subnav.offsetTop - diannaoTop
        document.onscroll = function () {
            if (window.pageYOffset >= diannaoTop) {
                subnav.style.position = 'fixed';
                //此时侧导航的top值就是没滚动前该元素offsetTop-滚到目标位置的offsetTop值
                subnav.style.top = subnavTop + 'px';
            } else {
                subnav.style.position = 'absolute';
                subnav.style.top = '800px'
            }
            console.log(flag);
            if (flag) {
                //3.頁面滚动到数组中指定区域,让对应的侧导航显示
                list.forEach((item, index) => {
                    if (window.pageYOffset >= item) {
                        for (var i = 0; i < li.length; i++) {
                            li[i].style.backgroundColor = ''
                        }
                        li[index].style.backgroundColor = 'pink'
                    }
                })
            }

        }
        var list = [floor.children[0].offsetTop, floor.children[1].offsetTop, floor.children[2].offsetTop, floor.children[3].offsetTop]
        //2.在li中点谁谁高亮,并且要滚动到相应的位置
        var flag = true
        for (var i = 0; i < li.length; i++) {
            li[i].setAttribute('data-index', i);

            li[i].onclick = function () {
                //在点击时候页面肯定会滚动,所以上面的滚动事件会影响到元素背景显示,这时候就需要在点击之后停止页面滚动的监听,滚动结束在开启
                flag = false;
                for (var i = 0; i < li.length; i++) {
                    li[i].style.backgroundColor = ''
                }
                this.style.backgroundColor = 'pink';
                //获取当前点击的li索引
                var index = this.getAttribute('data-index');
                //滚动的距离应该是对应数组中的位置
                animate(window, list[index], function () {
                    //动画滚动完成,让flag变为true,可以继续监听页面滚动事件了
                    flag = true;
                })

            }
        }
		//封装一个函数,主要是实现页面可以滚动
        function animate(obj, target, callback) {
            clearInterval(obj.timer);
            obj.timer = setInterval(() => {
                var tept = (target - obj.pageYOffset) / 10;
                tept = tept > 0 ? Math.ceil(tept) : Math.floor(tept);
                if (window.pageYOffset == target) {
                    clearInterval(obj.timer);
                    callback && callback()
                }
                console.log(tept);
                window.scroll(0, window.pageYOffset + tept)
            }, 30)
        }
    </script>
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值