原生 JavaScript 实现浮动层跟随页面滚动效果

洛溪
洛溪
发布时间:2026-10-15| 3人浏览过
原创

本文介绍一种使用原生 JavaScript 实现的网页“吸顶”或“粘滞”效果方案。通过监听滚动事件并动态计算位置,可以让指定的浮层在达到特定阈值后固定显示,离开屏幕可视区域或超出范围时恢复原状,无需依赖 jQuery 插件。

实现原理

实现浮动层跟随滚动的核心在于两个阶段的状态切换:

  1. 普通滚动模式:当页面向下滚动,但目标容器尚未完全消失在可视区域上方时,该浮动层应随页面正常移动(保持 position: relative/absolute)。
  2. 固定吸附模式:当目标容器的底部边界低于设定的“吸顶线”,但浮动层自身仍在可视范围内时,将样式切换为 position: fixed,使其固定在视口某处。
  3. 恢复原位模式:当目标容器彻底移出可视区域上方,或者用户向上滚动导致浮动层重新进入相对定位区间时,移除固定样式。

HTML 结构准备

假设我们需要一个侧边栏浮动框,并在主内容区域设置触发点。请确保 HTML 结构清晰,以便 JS 能够准确获取各元素的位置信息。

<!-- 页面主要内容区,用于控制何时结束吸顶 -->
<div id="mainContent" style="height: 3000px; padding-top: 50px;>
    <p>这里是页面主要内容...</p>
</div>

<!-- 需要实现跟随效果的浮动层 -->
<div id="floatingLayer" style="width: 200px; height: 300px; background: #f0f0f0; border: 1px solid #ccc;>
    浮动层内容
</div>

CSS 样式定义

默认状态下,浮动层应为 absolute 或 relative 定位,位于父容器中。当激活吸附状态时,JS 会将其添加 fixed 类名或覆盖内联样式。

#floatingLayer {
    width: 200px;
    height: 300px;
    /* 初始状态设为 absolute */
    position: absolute;
    right: 10px;
    top: 156px; /* 初始垂直偏移量 */
    background-color: #eee;
    transition: all 0.3s ease; /* 增加平滑过渡效果 */
}

/* 固定状态的样式类 */
#floatingLayer.is-fixed {
    position: fixed !important;
    top: 10px !important; /* 固定在视口顶部下方 10px */
    right: 10px;
    z-index: 999;
}

JavaScript 逻辑编写

以下为完整的原生 JS 实现代码,包含注释说明关键参数。

document.addEventListener('DOMContentLoaded', function () {
    // 1. 获取关键 DOM 元素
    var floatingEl = document.getElementById('floatingLayer');
    var mainEl = document.getElementById('mainContent');
    
    // 2. 定义配置参数
    var config = {
        offsetTop: 156, // 浮动层距离其父容器顶部的初始偏移(CSS中的top值)
        stickTop: 10    // 固定时距离视口顶部的像素值
    };

    // 3. 初始化位置(必须执行一次以获取准确的初始 Top 值)
    updatePosition();

    // 4. 绑定滚动事件
    window.addEventListener('scroll', updatePosition);

    function updatePosition() {
        // 如果元素不可见,则不处理
        if (!floatingEl.offsetParent) return;

        // 获取元素当前相对于文档的 Y 坐标
        var currentTop = floatingEl.getBoundingClientRect().top + window.pageYOffset;
        
        // 获取页面当前滚动的高度
        var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
        
        // 获取浮动层的自身高度
        var elHeight = floatingEl.offsetHeight;
        
        // 获取主内容区域的总高度和起始位置
        var mainRect = mainEl.getBoundingClientRect();
        var mainStart = scrollTop + mainRect.top;
        var mainEnd = mainStart + mainRect.height;

        // --- 判断逻辑 ---

        // A. 浮动层未到达吸顶线,或者是从上面滑过来的
        // 条件:当前滚动高度 + 浮动层初始offset > 浮动层绝对位置
        // 简化理解:如果页面的“天花板”还没推到浮动层的下面
        var isNotSticky = (scrollTop + config.offsetTop) > currentTop;
        
        // B. 检查是否超出了底部长尾内容(防止吸到底部外面去)
        var isBottomExceeded = (scrollTop + elHeight + config.stickTop) > mainEnd;

        // 判定是否需要处于 Fixed 状态
        var shouldBeFixed = !isNotSticky && !isBottomExceeded;

        if (shouldBeFixed) {
            // 应用 Fixed 样式
            floatingEl.classList.add('is-fixed');
            // 同步宽高,防止固定定位导致宽度塌陷
            floatingEl.style.width = floatingEl.offsetWidth + 'px';
            floatingEl.style.right = '10px'; // 保持右侧间距
        } else {
            // 恢复 Absolute 样式
            floatingEl.classList.remove('is-fixed');
            // 清理内联宽度样式,使其回归 CSS 定义的宽度
            floatingEl.style.width = '';
        }
    }
});

关键点解析

  • getBoundingClientRect():相比 offsetTop,它返回的是元素相对于视口的精确位置,配合滚动计算更为直观准确。
  • 底部边界检测:很多初学者忽略了对内容底部(mainEnd)的判断。如果不做此判断,当长文章结束时,吸顶的侧边栏可能会停留在屏幕中间或底部之外,造成体验不佳。
  • 性能优化:实际生产环境中,建议在 scroll 事件中加上防抖(Debounce)处理,或使用 requestAnimationFrame,以避免高频滚动带来的卡顿。

常见问题排查

问题一:页面刷新后位置跳变

原因通常是在没有执行初始 updatePosition 的情况直接绑定了 scroll 事件。必须在 DOMContentLoaded 时先跑一遍逻辑确定初始状态。

问题二:Fixed 模式下宽度变窄

当元素变为 position: fixed 时,它将脱离原来的文档流,如果在 HTML 中是宽度的百分比或者由父级撑开的,固定后会收缩。此时需通过 JS 动态计算 element.offsetWidth 并将其赋值给固定后的元素宽度。

以上就是原生JavaScript实现DIV浮动层跟随页面滚动效果的详细内容,更多关于前端网页交互技术的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。