高亮显示错误

高亮显示错误

问题描述:为什么不加1的话用鼠标点击导航条高亮定位错误,offsetTop的值是整数,scrollTop的值却是有很多小数的,导致高亮显示错误。我在第111行加了1

   

相关代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .content-part{
            width: 700px;
            background-color: rgba(0,0,0,.6);
            margin: 0px auto;
            margin-bottom: 30px;
            text-align: center;
            font-size: 40px;
        }
        .part1{
            height: 400px;
        }
        .part2{
            height: 430px;
        }
        .part3{
            height: 480px;
        }
        .part4{
            height: 530px;
        }
        .part5{
            height: 670px;
        }
        nav{
            width: 60px;
            height: 150px;
            background-color: orange;
            position:fixed;
            right: 10px;
            top: 50%;
            margin-top: -75px;
        }
        nav ul{
            width: 60px;
            list-style: none;
        }
        nav ul li{
            height: 30px;
            line-height: 30px;
            text-align: center;
            cursor: pointer;
        }
        nav ul li.cur{
            background-color: purple;
        }
    </style>
</head>
<body>
    <!-- 要使用到绝对定位和data-自定义属性 -->
    <!-- offsetTop属性,此元素定位祖先元素的垂直距离,祖先元素就是离自己最近的且拥有定位属性的元素 -->
    <!-- 1、楼层导航 -->
    <!-- 每个内容区域和导航条是通过data-n属性来建立连接 -->
    <!-- 2、窗口卷动到哪个位置,导航条对应位置有高光 -->
    <nav>
        <ul id="list">
            <li data-n="新闻">新闻</li>
            <li data-n="娱乐">娱乐</li>
            <li data-n="天气">天气</li>
            <li data-n="图片">图片</li>
            <li data-n="视频">视频</li>
        </ul>
    </nav>
    <!-- 每个单独板块 -->
    <section class="content-part part1" data-n="新闻">新闻</section>
    <section class="content-part part2" data-n="娱乐">娱乐</section>
    <section class="content-part part3" data-n="天气">天气</section>
    <section class="content-part part4" data-n="图片">图片</section>
    <section class="content-part part5" data-n="视频">视频</section>
    <script>
        //获取ul元素
        var list=document.getElementById('list');
        //获取section元素
        var section = document.querySelectorAll('.content-part');
        //获取li元素
        var liS = document.querySelectorAll('#list li');

        //获取每个内容区域距离顶部值,并存入数组
        var offsetTopArr = [];
        for(var i =0;i<section.length;i++){
            offsetTopArr.push(section[i].offsetTop);
        }
        //给数组的最后一项推入无穷大值,防止楼层出错,因为用户可能从后面往前翻,如果当前滚动到的值为5,就会出错
        //li标签也给不了.cur的选择器
        offsetTopArr.push(Infinity);
        console.log(offsetTopArr);
        var contentPart;
        //list的事件监听用的是事件委托,采用冒泡阶段
        list.onclick=function(e){
            //源元素的标签名字是li时
            if(e.target.tagName.toLowerCase()=='li'){
                //获取非w3c标准的属性名用getAttribute
                var n =e.target.getAttribute('data-n');
                //使用属性选择器来获取带有某个data-n属性的标签,方括号指带有某种属性元素
                contentPart=document.querySelector('.content-part[data-n='+n+']');
                //用document.documentElement.scrollTop来设置距离页面顶部的位置
                //不加1鼠标点击li标签高亮定位错误,(点击楼层3,高亮在楼层2)
                document.documentElement.scrollTop = contentPart.offsetTop + 1;
                console.log(document.documentElement.scrollTop);
            }
        }

        var floor = -1;
        //建立页面滚动事件监听,楼层从0-4
        window.onscroll=function(){
            var scrollTop =document.documentElement.scrollTop;
            //for循环offsetTop数组,判断滚动的距离是否介于哪两项之间
            for(var i = 0;i<offsetTopArr.length;i++){
                if( scrollTop>=offsetTopArr[i] && scrollTop<=offsetTopArr[i+1]){
                    break;
                }
            }
           
            //var一个floor变量,意思为当前楼层,防止一直在输出楼层,当当前楼层和滚动到的不一致时,才输出i
            //记得把当前楼层赋值给floor变量
            if(floor != i){
                console.log('当前楼层时'+ i +'滚动值' + scrollTop);
                floor = i;
                for(var j =0;j<liS.length;j++){
                    if(i==j){
                        liS[j].className = 'cur';
                    }else{
                        liS[j].className = '';
                    }
            }

            }
           
        }

    </script>
</body>
</html>

       

下载视频          

下载视频          

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,解答如下:

1、这边测试代码chrome版本是

https://img1.sycdn.imooc.com//climg/616a3abf09ecebb604000118.jpg

滚动值不是小数

https://img1.sycdn.imooc.com//climg/616a3af609bb85d306600139.jpg

https://img1.sycdn.imooc.com//climg/616a3afc0955690e02370188.jpg

可能是chrome版本导致的显示小数,建议用Math.round()方法包裹转化一下。

2、代码中加1才能让右侧高亮显示正确

https://img1.sycdn.imooc.com//climg/616a3b49090e624707410039.jpg

是因为第一楼不需要滚动,也不会进入onscroll事件中,所以第一层导航没有高亮。建议将加1去掉,在第一层导航元素上添加类

https://img1.sycdn.imooc.com//climg/616a3bbd098e2dae05370117.jpg

https://img1.sycdn.imooc.com//climg/616a3bf40996a6e406940061.jpg

3、在滚动的时候,不需要等于下一楼的值,避免导航不准,小于即可

https://img1.sycdn.imooc.com//climg/616a3bff09da1d3b08730173.jpg

祝学习愉快!

  • Snakk 提问者 #1

    谢谢老师,差不多理解了。

    1、把document.documentElement.scrollTop用Math.round()四舍五入,让值为整数(我的版本也是最新,不知为啥是小数)(主要要注意这点,可以让高光正确显示)

    2、第0层楼无需滚动,给第一个li标签添加cur的class选择器,一进入页面第一个li就有高亮

    3、滚动事件监听那里,scrollTop小于下一个楼层高度即可

    下载视频          
    2021-10-16 10:56:48
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师