基础平滑滚动(最常用)

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

jquery网页锚点滚动过渡特效代码
(图片来源网络,侵删)

实现思路

  1. 监听所有锚点链接(href 以 开头)的点击事件。
  2. 阻止默认的瞬间跳转行为。
  3. 获取目标元素的 id(从 href 属性中提取)。
  4. 使用 jQuery 的 animate() 方法,将 htmlbody 元素的 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>

带进度指示器和激活状态的滚动

这个方案在方案一的基础上增加了两个功能:

  1. 滚动进度条:显示当前页面的滚动进度。
  2. 导航激活状态:当滚动到某个区域时,自动高亮对应的导航链接。

实现思路

  1. 平滑滚动:同方案一。
  2. 滚动监听:监听 windowscroll 事件。
  3. 进度条:根据 window.scrollTop()document.height() 计算滚动百分比,并更新进度条的宽度。
  4. 激活状态:遍历所有锚点区域,判断哪个区域当前在视口中,然后给对应的导航链接添加激活类(如 .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)的高级滚动

这个方案允许你使用不同的缓动函数,让滚动效果更自然,比如先快后慢,或者先慢后快再慢。

实现思路

  1. 引入 Easing 插件:jQuery 的 animate 方法默认只支持 linearswing 两种缓动,要使用更多效果,需要引入 jQuery Easing 插件。
  2. 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 的灵活性和扩展性(如无法添加回调或自定义缓动)。

您可以根据您的具体需求和项目复杂度,选择最适合的方案进行修改和使用。

jquery网页锚点滚动过渡特效代码
(图片来源网络,侵删)
jquery网页锚点滚动过渡特效代码
(图片来源网络,侵删)