老师 有关楼层导航条效果实现的问题

老师 有关楼层导航条效果实现的问题

http://img1.sycdn.imooc.com//climg/606f2c6609cf33b307430638.jpg

这一段不是特别理解,老师可以讲解一下吗,还有最终实现效果有点问题(在导航条显示选中)

<!DOCTYPE html>

<html>


<head>

<meta charset="UTF-8">

<title></title>

<style type="text/css">

* {

margin: 0;

padding: 0;

}

.content-part {

width: 1000px;

margin: 0px auto;

margin-bottom: 30px;

background-color: #ccc;

font-size: 50px;

}

.floornav {

width: 80px;

height: 200px;

position: fixed;

top: 50%;

margin-top: -100px;

right: 0px;

background-color: rgba(0, 0, 0, .6);

color: white;

}

.floornav ul {

width: 80px;

height: 200px;

list-style: none;

}

.floornav li {

width: 80px;

height: 40px;

line-height: 40px;

text-align: center;

/*小手状*/

cursor: pointer;

}

.floornav ul li.current {

background-color: rgba(0,0,0,.3);

color: white;

}

</style>

</head>


<body>

<nav class="floornav">

<ul id="list">

<li data-n="科技" class="current">科技</li>

<li data-n="体育">体育</li>

<li data-n="新闻">新闻</li>

<li data-n="娱乐">娱乐</li>

<li data-n="视频">视频</li>

</ul>

</nav>


<section class="content-part" style="height:674px;" data-n="科技">

科技栏目

</section>


<section class="content-part" style="height:567px;" data-n="体育">

体育栏目

</section>


<section class="content-part" style="height:739px;" data-n="新闻">

新闻栏目

</section>


<section class="content-part" style="height:574px;" data-n="娱乐">

娱乐栏目

</section>


<section class="content-part" style="height:1294px;" data-n="视频">

视频栏目

</section>


<script type="text/javascript">

var list = document.getElementById('list');

var contentParts = document.querySelectorAll('.content-part');

var lis = document.querySelectorAll('#list li');


// 使用事件委托给li添加监听

list.onclick = function(e) {

//e.target.tagName.toLowerCase()获取到点击的标签名,并转换成小写

if(e.target.tagName.toLowerCase() == 'li') {

//getAttribute表示得到标签身上的某个属性值

var n = e.target.getAttribute('data-n');


//可以用属性选择器(就是方括号选择器)来寻找带有相同data-n的content-part

var contentPart = document.querySelector('.content-part[data-n=' + n + ']');


//让页面的卷动自动成为这个盒子的offsetTop值

document.documentElement.scrollTop = contentPart.offsetTop;

}

}


// 在页面加载好之后,将所有的content-part盒子的offsetTop值推入数组

var offsetTopArr = [];


// 遍历所有的contentPart,将它们的净位置推入数组

for(var i = 0; i < contentParts.length; i++) {

offsetTopArr.push(contentParts[i].offsetTop);

}

// 为了最后一项可以方便比较,我们可以推入一个无穷大

offsetTopArr.push(Infinity);


console.log(offsetTopArr);


// 当前所在楼层

var nowfloor = -1;


// 窗口的卷动

window.onscroll = function() {

// 得到当前的窗口卷动值

var scrollTop = document.documentElement.scrollTop;


// 遍历offsetTopArr数组,看看当前的scrollTop值在哪两个楼层之间

for(var i = 0; i < offsetTopArr.length; i++) {

if(scrollTop >= offsetTopArr[i] && scrollTop < offsetTopArr[i + 1]) {

break;

}

}

// 退出循环的时候,i是几,就表示当前楼层是几

// 如果当前所在楼层,不是i,表示换楼了

if(nowfloor != i) {

console.log(i);

// 让全局变量改变为这个楼层号

nowfloor = i;


// 设置下标为i的项有cur

for(var j = 0; j < lis.length; j++) {

if(j == i) {

lis[j].className = 'current';

} else {

lis[j].className = '';

}

}

}

};

</script>

</body>


</html>


正在回答

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

1回答

同学你好,关于同学的问题解答如下

1、老师测试了同学的代码,效果是能够实现的,如图

http://img1.sycdn.imooc.com//climg/6070161a0a37370019160968.jpg

同学说的导航条选中有问题指的是左侧楼层模块与右侧导航不能精准判断么?该问题产生的原因是因为左侧的楼层模块高度不一致,而在js判断卷动到哪里的时候,判断的是在那两个楼层模块之间导致的。因为不是确切的指定了卷动值,所以这一现象是正常现象呢。

http://img1.sycdn.imooc.com//climg/6070178409badd8f09330181.jpg

2、关于同学说的对代码不理解,老师帮你写在了代码注释里面

http://img1.sycdn.imooc.com//climg/60701a5c0924a5d312350745.jpg

希望可以帮到你,如果还有疑问,可以再次提问。祝学习愉快!


  • lcy_18 提问者 #1

    那左侧楼层模块与右侧导航要怎样才能进行精准判断呢?

    2021-04-09 17:44:00
  • 卡布琦诺 回复 提问者 lcy_18 #2

    同学你好,有一种比较精准的实现方案如下:

    1、首先分析实现思路

    (1)因为是由滚动触发的楼层判断,所以肯定离不开onscroll事件。

    (2)要获取每个楼层顶端距离视窗顶部的距离,随着滚动条往下滚动,此距离会不断缩小,当接近到某个距离时我们判定某个楼层模块进入可视区域(当然其它楼层都满足此判定)。

    2、实现思路图示

    为了方便理解,假设楼层模块一顶端距离视窗顶端为0时,此时判定楼层一模块进入可视区域,即楼层导航中第一个按钮应该被点亮。

    http://img1.sycdn.imooc.com//climg/6070365709925b8108760502.jpg

    此时楼层模块一距离顶端已经为0,可以得出当楼层模块的offsetTop = scrollTop时,我们认定

    楼层模块一进入可视区域。而当楼层模块二进去可视区时,楼层模块二的offsetTop也等于滚动条的距离,此时楼层模块二自然会进入可视区域。

    http://img1.sycdn.imooc.com//climg/60703782092a094508690686.jpg

    现在得到了判断各个楼层模块进入可视区域的条件,如果某个楼层模块的offsetTop属性的值小于等于滚动条距离时(如果用等于条件过于苛刻,很难刚好滚动到这个距离点上),高亮显示右侧相对应的导航项。

    为了让效果更加自然,不能真的让某个楼层模块紧贴可视区顶部时才判定它满足条件,而是提前达到某个距离就判定满足,所以真正的条件应该是offsetTop - 100(这个数字看自己感觉进行调整) <= scrollTop,然后利用满足楼层的索引来控制样式,而后者满足条件的索引始终会覆盖前面的索引,所以右侧高亮显示的导航项只有一个

    3、代码如下:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    * {
    padding: 0;
    margin: 0;
    list-style: none;
    }
    .floor>div {
    height: 900px;
    line-height: 900px;
    text-align: center;
    color: #fff;
    font-size: 40px;
    }
    .floorNav {
    width: 100px;
    height: 200px;
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    background: #ddd;
    }
    .floorNav>li {
    height: 40px;
    line-height: 40px;
    text-align: center;
    color: #fff;
    }
    .active {
    background: #e4393c;
    color: #fff;
    }
    </style>
    </head>
    <body>
    <div class="floor">
    <div style="background: #ffb6b9">楼层模块一</div>
    <div style="background: #fae3d9">楼层模块二</div>
    <div style="background: #bbded6">楼层模块三</div>
    <div style="background: #8ac6d1">楼层模块四</div>
    <div style="background: #fff1ac">楼层模块五</div>
    </div>
    <ul class="floorNav">
    <li>导航一</li>
    <li>导航二</li>
    <li>导航三</li>
    <li>导航四</li>
    <li>导航五</li>
    </ul>
    <script>
    //获取楼层
    var floors = document.querySelectorAll(".floor>div");
    //获取楼层导航
    var floorNavs = document.querySelectorAll(".floorNav>li");
    //滚动监听
    window.onscroll = function() {
    //获取滚动条高度(并且兼容ie)
    var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    //符合点亮条件的楼层索引
    var activeIndex;
    //楼层导航图标点亮控制
    floors.forEach((floor, index) => {
    //检查各楼层顶端距离视窗顶端距离,如果满足条件则修改楼层图标
    floor.offsetTop - 100 <= scrollTop ? activeIndex = index : null;
    });
    //根据索引数设置楼层样式
    floorNavs.forEach((nav, index) => {
    index === activeIndex ? nav.classList.add('active') : nav.classList.remove('active');
    });
    };
    </script>
    </body>
    </html>

    说明:这个也不是完全精准的实现方案,前面也提到了,如果是完全精准的,判定条件过于苛刻,很难刚好滚动到这个距离点上,所以我们设置了一个范围值。

    希望可以帮到你,祝学习愉快!

    2021-04-09 19:24:44
  • lcy_18 提问者 回复 卡布琦诺 #3

    http://img1.sycdn.imooc.com//climg/607077f509bb6a2407840354.jpg

    这个是什么意思

    2021-04-09 23:51:45
问题已解决,确定采纳
还有疑问,暂不采纳

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

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

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

在线咨询

领取优惠

免费试听

领取大纲

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