本文介绍如何使用原生JavaScript实现网站楼层导航的高亮效果。通过监听onscroll事件,结合offsetTop与scrollTop的计算,判断当前视窗内的楼层,并动态切换导航项的CSS类名。文章提供了完整的HTML结构、CSS样式及JS逻辑代码,旨在为开发者提供清晰的实现思路与代码参考。
引言
引言
在楼层导航功能中,一个关键交互是当用户滚动页面至特定楼层时,侧边导航栏对应的图标或按钮应同步高亮显示,以指示当前所在区域。
鉴于本文不使用jQuery,我们将采用原生JavaScript来实现这一功能。实现的核心在于明确触发高亮的滚动条件,具体效果如下所示:

实现思路
实现思路
首先,由于高亮状态由页面滚动触发,因此必须监听页面的滚动事件。
其次,我们需要计算每个楼层顶部距离视口顶部的距离。随着页面滚动,该距离值会发生变化。当此距离减小到一定阈值时,我们认为该楼层已进入可视区域,从而触发高亮逻辑。
在jQuery中,通常使用offset().top方法获取元素距离文档顶部的距离。而在原生JavaScript中,仅能获取offsetTop属性,该属性返回元素相对于最近定位祖先元素(position非static)的偏移量,且该值不随滚动条移动而改变。
虽然可以通过计算模拟jQuery的offset().top值,但在此场景下并非必要。
基于前文分析,我们可以得出关系式:offset().top = offsetTop - scrollTop(其中offsetTop参考对象为根元素)。
为便于理解,假设楼层壹顶端距视窗顶端为0时,判定楼层壹入画,此时楼层导航中第一个按钮应被点亮。

根据公式offset().top = offsetTop - scrollTop,当楼层一顶部与视口顶部距离为0时,即offsetTop等于scrollTop,此时可认定楼层一进入可视区域。
当楼层二进入可视区域时,楼层二的offsetTop同样等于当前的滚动距离,此时楼层一自然移出可视区域。

由此得出判断楼层进入可视区域的条件:若某楼层的offsetTop值小于或等于当前滚动条距离(scrollTop),则点亮对应楼层的导航图标。使用小于等于而非严格等于,是为了避免因滚动精度问题导致无法触发高亮。
为了提升用户体验,避免楼层紧贴视口顶部时才触发高亮,通常会在判定中加入一个提前量。因此,实际判定条件调整为:offsetTop - 100 <= scrollTop(其中100为预设的提前距离,可根据实际需求调整)。
可能存在疑问:当楼层二进入可视区域时,楼层一是否仍满足offsetTop <= scrollTop的条件?在jQuery中,通常通过移除兄弟元素的class来确保只有一个高亮。
在原生JavaScript中,处理方式类似。我们通过满足条件的楼层索引来控制样式,后满足条件的索引会覆盖之前的索引,从而保证始终只有一个导航项处于高亮状态。
理清上述逻辑后,代码实现便相对清晰。以下是具体的实现代码:
实现代码
实现代码
HTML结构部分:
<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>
CSS样式部分:
* {
padding: 0;
margin: 0;
list-style: none;
}
.floor>div {
height: 900px;
line-height: 900px;
text-align: center;
color: #fff;
font-size: 40px;
}
.floorNav {
width: 40px;
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;
}
JavaScript逻辑部分:
//获取楼层
let floors = document.querySelectorAll(".floor>div");
//获取楼层导航
let floorNavs = document.querySelectorAll(".floorNav>li");
//滚动监听
window.onscroll = function () {
//获取滚动条高度,兼容ie
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
//符合点亮条件的楼层索引
let 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');
});
};
需注意,代码中使用了classList对象的add和remove方法。这两个方法在IE浏览器中不支持,由于本文场景无需兼容IE,故直接采用。
本文仅提供了楼层导航高亮效果的基本实现思路,代码并非最优解。若有更佳的实现方案,欢迎留言讨论。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。