基础平滑滚动(最常用)
这是最简单、最基础的实现方式,点击链接后,页面会平滑地滚动到目标位置,而不是瞬间跳转。

(图片来源网络,侵删)
实现思路
- 监听所有锚点链接(
href以 开头)的点击事件。 - 阻止默认的瞬间跳转行为。
- 获取目标元素的
id(从href属性中提取)。 - 使用 jQuery 的
animate()方法,将html或body元素的scrollTop属性动画化到目标元素的位置。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">基础平滑滚动特效</title>
<style>
/* 基础样式,用于演示 */
html {
scroll-behavior: smooth; /* CSS 实现方式,可作为后备方案 */
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
}
nav {
position: fixed;
top: 0;
width: 100%;
background-color: #333;
z-index: 1000;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
nav li {
margin: 0 20px;
}
nav a {
color: white;
text-decoration: none;
padding: 20px 0;
display: block;
transition: color 0.3s;
}
nav a:hover {
color: #f0f0f0;
}
section {
height: 100vh; /* 每个部分占满一屏 */
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: white;
}
#section1 { background-color: #e74c3c; }
#section2 { background-color: #3498db; }
#section3 { background-color: #2ecc71; }
#section4 { background-color: #f39c12; }
</style>
</head>
<body>
<nav>
<ul>
<li><a href="#section1">第一部分</a></li>
<li><a href="#section2">第二部分</a></li>
<li><a href="#section3">第三部分</a></li>
<li><a href="#section4">第四部分</a></li>
</ul>
</nav>
<section id="section1">第一部分内容</section>
<section id="section2">第二部分内容</section>
<section id="section3">第三部分内容</section>
<section id="section4">第四部分内容</section>
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// 当点击 nav 中的 a 标签时
$('nav a').on('click', function(event) {
// 1. 阻止默认的锚点跳转行为
event.preventDefault();
// 2. 获取点击链接的 href 属性值("#section2")
var target = $(this).attr('href');
// 3. 获取目标元素相对于文档顶部的偏移量
var targetOffset = $(target).offset().top;
// 4. 使用 animate 方法平滑滚动到目标位置
// 'html, body' 是为了兼容不同的浏览器
// scrollTop: targetOffset 是滚动到的最终位置
// 800 是动画持续时间(毫秒)
// 'swing' 是缓动函数
// function() 是动画完成后的回调函数
$('html, body').animate({
scrollTop: targetOffset
}, 800, 'swing', function() {
// 可选:滚动完成后,可以在这里执行一些操作
// console.log('滚动完成!');
});
});
});
</script>
</body>
</html>
带进度指示器和激活状态的滚动
这个方案在方案一的基础上增加了两个功能:
- 滚动进度条:显示当前页面的滚动进度。
- 导航激活状态:当滚动到某个区域时,自动高亮对应的导航链接。
实现思路
- 平滑滚动:同方案一。
- 滚动监听:监听
window的scroll事件。 - 进度条:根据
window.scrollTop()和document.height()计算滚动百分比,并更新进度条的宽度。 - 激活状态:遍历所有锚点区域,判断哪个区域当前在视口中,然后给对应的导航链接添加激活类(如
.active),并移除其他链接的该类。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">高级平滑滚动特效</title>
<style>
/* 基础样式 */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
}
/* 进度条样式 */
.progress-bar {
position: fixed;
top: 0;
left: 0;
height: 4px;
background-color: #3498db;
z-index: 1001;
width: 0%;
transition: width 0.2s ease;
}
nav {
position: fixed;
top: 10px; /* 给进度条留出空间 */
width: 100%;
background-color: rgba(51, 51, 51, 0.9);
z-index: 1000;
padding: 10px 0;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
nav li {
margin: 0 20px;
}
nav a {
color: white;
text-decoration: none;
padding: 10px 15px;
border-radius: 5px;
transition: all 0.3s;
}
/* 激活状态的样式 */
nav a.active {
background-color: #3498db;
font-weight: bold;
}
section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: white;
padding-top: 60px; /* 防止内容被导航栏遮挡 */
box-sizing: border-box;
}
#section1 { background-color: #e74c3c; }
#section2 { background-color: #3498db; }
#section3 { background-color: #2ecc71; }
#section4 { background-color: #f39c12; }
</style>
</head>
<body>
<!-- 进度条 -->
<div class="progress-bar"></div>
<nav>
<ul>
<li><a href="#section1" class="nav-link active">第一部分</a></li>
<li><a href="#section2" class="nav-link">第二部分</a></li>
<li><a href="#section3" class="nav-link">第三部分</a></li>
<li><a href="#section4" class="nav-link">第四部分</a></li>
</ul>
</nav>
<section id="section1">第一部分内容</section>
<section id="section2">第二部分内容</section>
<section id="section3">第三部分内容</section>
<section id="section4">第四部分内容</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
// 平滑滚动功能
$('a[href^="#"]').on('click', function(event) {
event.preventDefault();
var target = $(this.getAttribute('href'));
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top - 60 // 减去导航栏高度,避免遮挡
}, 800, 'swing');
}
});
// 滚动时更新进度条和导航激活状态
$(window).on('scroll', function() {
// 1. 更新进度条
var scrollTop = $(window).scrollTop();
var docHeight = $(document).height() - $(window).height();
var scrollPercent = (scrollTop / docHeight) * 100;
$('.progress-bar').width(scrollPercent + '%');
// 2. 更新导航激活状态
var scrollPosition = $(this).scrollTop();
// 遍历所有锚点链接
$('.nav-link').each(function() {
var currLink = $(this);
var refElement = $(currLink.attr('href'));
// 如果目标元素存在,并且当前滚动位置超过了目标元素的顶部
if (refElement.position().top - 61 <= scrollPosition) {
$('.nav-link').removeClass("active"); // 先移除所有active类
currLink.addClass("active"); // 再给当前链接添加active类
}
});
});
});
</script>
</body>
</html>
带缓动函数(Easing)的高级滚动
这个方案允许你使用不同的缓动函数,让滚动效果更自然,比如先快后慢,或者先慢后快再慢。
实现思路
- 引入 Easing 插件:jQuery 的
animate方法默认只支持linear和swing两种缓动,要使用更多效果,需要引入 jQuery Easing 插件。 - 在
animate中指定缓动函数:调用animate时,在持续时间参数后面添加缓动函数名作为第四个参数。
完整代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">带缓动函数的平滑滚动</title>
<style>
/* 基础样式,与方案一类似 */
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
line-height: 1.6;
margin: 0;
padding: 0;
}
nav {
position: fixed;
top: 0;
width: 100%;
background-color: #333;
z-index: 1000;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
nav li {
margin: 0 20px;
}
nav a {
color: white;
text-decoration: none;
padding: 20px 0;
display: block;
}
section {
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: white;
}
#section1 { background-color: #9b59b6; }
#section2 { background-color: #1abc9c; }
#section3 { background-color: #e67e22; }
#section4 { background-color: #34495e; }
</style>
</head>
<body>
<nav>
<ul>
<li><a href="#section1" data-easing="swing">Swing (默认)</a></li>
<li><a href="#section2" data-easing="linear">Linear (匀速)</a></li>
<li><a href="#section3" data-easing="easeInOutQuad">InOutQuad (先慢后快再慢)</a></li>
<li><a href="#section4" data-easing="easeOutBounce">OutBounce (弹跳)</a></li>
</ul>
</nav>
<section id="section1">第一部分内容</section>
<section id="section2">第二部分内容</section>
<section id="section3">第三部分内容</section>
<section id="section4">第四部分内容</section>
<!-- 引入 jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- 引入 jQuery Easing 插件 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<script>
$(document).ready(function() {
$('nav a').on('click', function(event) {
event.preventDefault();
var target = $(this).attr('href');
var targetOffset = $(target).offset().top;
// 从 data-easing 属性获取缓动函数名,如果没有则默认为 'swing'
var easing = $(this).data('easing') || 'swing';
$('html, body').animate({
scrollTop: targetOffset
}, 1200, easing, function() {
// 滚动完成后的回调
// console.log('使用 ' + easing + ' 缓动函数滚动完成!');
});
});
});
</script>
</body>
</html>
总结与选择建议
| 方案 | 特点 | 适用场景 | 核心代码 |
|---|---|---|---|
| 基础平滑滚动 | 简单、轻量、兼容性好 | 个人博客、作品集、简单的单页网站 | $('html, body').animate({scrollTop: targetOffset}, 800); |
| 高级特效 | 带进度条、导航高亮,交互体验更佳 | 企业官网、产品介绍页、需要引导用户浏览的长页面 | $(window).on('scroll', ...) + $('.progress-bar').width(...) |
| 缓动函数 | 动画效果更丰富、更自然、更具趣味性 | 创意网站、强调视觉体验的页面 | $('html, body').animate(..., 1200, 'easeInOutQuad'); |
重要提示:
- 性能:对于非常长的页面,频繁的
scroll事件监听可能会影响性能,可以考虑使用 防抖(Debounce) 或 节流(Throttle) 技术来优化,Lodash.js 库提供了现成的_.throttle()和_.debounce()函数。 - CSS 替代方案:现代浏览器支持纯 CSS 的平滑滚动:
html { scroll-behavior: smooth; },这非常简单,但没有 JavaScript 的灵活性和扩展性(如无法添加回调或自定义缓动)。
您可以根据您的具体需求和项目复杂度,选择最适合的方案进行修改和使用。

(图片来源网络,侵删)

(图片来源网络,侵删)
