楼梯式导航是一种常见的网页交互设计,通常固定在页面一侧。当用户滚动浏览长页面时,它能直观地展示当前所处的内容板块,并支持点击快速跳转,极大地提升了用户体验。
本文将详细介绍如何使用原生 HTML、CSS 和 JavaScript 一步步实现一个功能完整的楼梯式导航效果。
一、构建基础页面结构与导航菜单
首先,我们需要创建基本的网页布局,包括头部、多个不同高度的内容板块、底部,以及左侧的导航菜单。
1. HTML 结构
我们使用 <section> 元素来创建多个内容板块,并为它们设置不同的背景色和高度类。同时,创建一个使用固定定位的 <div> 作为导航容器。
<!-- 模拟网站的头部 -->
<header class="header"></header>
<!-- 模拟网站的主体部分-->
<main class="main">
<section class="bg-skyblue h600">特色美食区推荐</section>
<section class="bg-tomato h400">数字动画</section>
<section class="bg-khaki h700">热销美食区推荐</section>
<section class="bg-pink h400">今日特价</section>
<section class="bg-tomato h500">限时优惠</section>
<section class="bg-aquamarine h800">美食欣赏</section>
</main>
<!-- 模拟网站的底部 -->
<footer class="footer"></footer>
<!-- 左侧楼梯式导航开始 -->
<div class="louti" id="J-louti">
<ul class="louti-list">
<li class="current">特色美食</li>
<li>数字动画</li>
<li>热销美食</li>
<li>今日特价</li>
<li>限时优惠</li>
<li>美食欣赏</li>
</ul>
</div>
<!-- 左侧楼梯式导航结束 -->
2. 核心 CSS 样式
CSS 部分定义了内容区域的样式,并设置了导航菜单的固定定位、列表样式以及高亮状态。
<style>
html, body { margin: 0; }
.header, .footer {
height: 300px;
background-color: #000;
}
section {
margin-bottom: 40px;
font-size: 80px;
display: flex;
align-items: center;
justify-content: center;
}
.main {
width: 800px;
margin: 50px auto;
}
/* 背景色类 */
.bg-skyblue { background-color: skyblue; }
.bg-khaki { background-color: khaki; }
.bg-tomato { background-color: tomato; }
.bg-pink { background-color: pink; }
.bg-aquamarine { background-color: aquamarine; }
/* 高度类 */
.h800 { height: 800px; }
.h700 { height: 700px; }
.h600 { height: 600px; }
.h500 { height: 500px; }
.h400 { height: 400px; }
/* 楼梯式导航样式 */
ul, li {
margin: 0;
list-style: none;
padding: 0;
}
.louti {
position: fixed;
top: 200px;
left: 20px;
display: none; /* 初始隐藏 */
}
ul.louti-list li {
line-height: 30px;
color: #73848c;
border-left: 2px solid #ddd;
text-indent: 10px;
cursor: pointer;
}
ul.louti-list li.current {
color: #1ec28b;
border-left-color: #1ec28b;
}
</style>

图1:包含多个区块的页面基础效果
二、实现原理与 JavaScript 交互逻辑
实现的核心在于建立导航项与内容板块的索引映射关系。我们为每个导航项和内容板块分配相同的序号(Index),通过 JavaScript 计算内容板块的位置,并处理点击和滚动事件。
1. 建立索引关联
首先,为每个导航项 (<li>) 和内容板块添加索引。内容板块需要添加一个特定的类名(如 louti-content)以便 JavaScript 获取。
<main class="main">
<section class="louti-content bg-skyblue h600">特色美食区推荐</section> <!-- 索引 0 -->
<section class="louti-content bg-tomato h400">数字动画</section> <!-- 索引 1 -->
<section class="louti-content bg-khaki h700">热销美食区推荐</section> <!-- 索引 2 -->
<section class="louti-content bg-pink h400">今日特价</section> <!-- 索引 3 -->
<section class="louti-content bg-tomato h500">限时优惠</section> <!-- 索引 4 -->
<section class="louti-content bg-aquamarine h800">美食欣赏</section> <!-- 索引 5 -->
</main>
2. JavaScript 实现步骤
接下来的交互逻辑是前端开发的核心,我们使用原生JavaScript来实现事件处理和DOM操作。完整的实现可以分为以下几个步骤:
-
步骤1:初始化数据
获取所有导航项和内容板块,并为导航项添加 index 属性。同时,计算并存储每个内容板块距离页面顶部的距离。
// 1. 获取左侧楼梯式导航中的所有li元素
var loutiList = document.querySelectorAll(".louti-list li");
// 2. 给每一个li元素添加一个序号属性
for (let i = 0; i < loutiList.length; i++) {
loutiList[i].index = i;
}
// 3. 获取所有楼梯式导航对应的内容区域
var loutiContent = document.querySelectorAll(".louti-content");
// 4. 计算每个内容区域距页面顶部的距离,存入数组
var loutiContentTop = [];
for (let i = 0; i < loutiContent.length; i++) {
loutiContentTop[i] = loutiContent[i].offsetTop;
}
-
步骤2:实现点击跳转
使用事件委托,将导航项列表的点击事件委托给其父元素<ul>处理,这是优化事件监听性能的常见技巧。当点击某个导航项时,根据其 index 滚动到对应的内容板块位置,并更新导航项的高亮状态。
// 5. 利用事件代理(委托),将li的点击事件委托给父元素ul
const loutiUl = document.querySelector(".louti-list");
loutiUl.addEventListener("click", function (e) {
const target = e.target;
// 判断点击的是否是li元素
if(target.tagName.toLowerCase() !== "li") return;
// 获取被点击li的序号
let index = target.index;
// 滚动到对应内容区域的顶部
window.scrollTo(0, loutiContentTop[index]);
// 更新高亮状态:移除所有,为当前项添加
for (let i = 0; i < loutiList.length; i++) {
loutiList[i].classList.remove("current");
}
target.classList.add("current");
});
-
步骤3:实现滚动自动高亮
监听页面的滚动事件。当滚动时,根据当前滚动距离判断用户所处的区域,并自动高亮对应的导航项。这里可以加入一个“提前量”逻辑,当滚动到前一个区域的约2/3处时,就高亮下一个区域,使交互更灵敏。
// 监听页面滚动事件,实现自动高亮
window.addEventListener("scroll", function () {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for (let i = 0; i < loutiContentTop.length; i++) {
// 判断逻辑:滚动距离 >= (当前区域顶部距离 - 上一个区域高度的1/3)
if (scrollTop >= loutiContentTop[i] - loutiContent[i - 1 > 0 ? i - 1 : 0].clientHeight * (1 / 3)) {
// 移除所有高亮
for (let j = 0; j < loutiList.length; j++) {
loutiList[j].classList.remove("current");
}
// 高亮当前项
loutiList[i].classList.add("current");
}
}
});
-
步骤4:添加响应式显示逻辑
最后,我们增加两个显示/隐藏导航的逻辑:
- 当页面滚动距离小于300px(例如在顶部)时,隐藏导航。
- 当浏览器窗口宽度小于992px时(适配小屏幕),隐藏导航。
同时监听 resize 事件,在窗口大小变化时重新判断。
function hideLouti() {
function handlerFn() {
if (window.scrollY < 300 || window.innerWidth < 992) {
document.querySelector("#J-louti").style.display = "none";
} else {
document.querySelector("#J-louti").style.display = "block";
}
}
window.addEventListener("scroll", handlerFn);
window.addEventListener("resize", handlerFn); // 窗口变化时也执行
handlerFn(); // 初始化执行一次
}
hideLouti();
三、完整源代码与效果
将以上所有 HTML、CSS 和 JavaScript 代码组合起来,即可得到一个功能完善的楼梯式导航。它支持点击跳转、滚动自动高亮,并且在移动端等小屏幕设备上会自动隐藏,确保布局不会错乱。

图2:集成所有功能后的楼梯式导航最终效果
这种导航模式非常适合商品分类页、长文档、单页应用(SPA)等场景。通过原生 JavaScript、HTML与CSS 的实现,我们不仅深入理解了其原理,也掌握了一项提升网页交互体验的实用技能。在实际项目中,你也可以利用事件代理等前端优化技巧,将这套逻辑封装成可复用的组件。