You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使Overlay Div在水平滚动的父Div中保持固定

固定在滚动容器两侧的滚动提示Overlay实现方案

要解决滚动提示Overlay随内容滚动移动的问题,核心是调整DOM结构和定位逻辑,让Overlay相对于滚动容器的父容器固定,同时修正滚动状态判断逻辑。以下是修复后的完整代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>可滚动圆形按钮</title>
    <style>
        /* 滚动容器父容器,用于定位Overlay */
        .scroll-container-wrapper {
            position: relative;
            width: 50%;
            margin-bottom: 20px;
        }
        .scrollable-div {
            width: 100%;
            overflow-x: auto;
            white-space: nowrap;
            padding: 10px 0; 
            /* 隐藏滚动条 */
            scrollbar-width: none;
        }
        .scrollable-div::-webkit-scrollbar {
            display: none; /* WebKit浏览器适配 */
        }
        .circular-btn {
            display: inline-block;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: #007bff;
            color: #fff;
            text-align: center;
            line-height: 40px;
            margin-right: 5px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.2s;
        }
        .circular-btn:hover {
            background-color: #0056b3;
        }
        .scroll-overlay {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 50px;
            pointer-events: none; /* 允许点击穿透到下方按钮 */
            opacity: 1;
            transition: opacity 0.2s;
        }
        .scroll-overlay-left {
            left: 0;
            background: linear-gradient(to right, rgba(255,255,255,0.8), transparent);
        }
        .scroll-overlay-right {
            right: 0;
            background: linear-gradient(to left, rgba(255,255,255,0.8), transparent);
        }
        .scroll-overlay.hidden {
            opacity: 0;
            pointer-events: none;
        }
        .selected {
            background-color: #28a745 !important;
        }
    </style>
</head>
<body>
    <div class="scroll-container-wrapper">
        <div class="scrollable-div" id="scrollableDiv">
            <!-- 圆形按钮列表 -->
            <div class="circular-btn selected">1</div>
            <div class="circular-btn">2</div>
            <div class="circular-btn">3</div>
            <div class="circular-btn">4</div>
            <div class="circular-btn">5</div>
            <div class="circular-btn">6</div>
            <div class="circular-btn">7</div>
            <div class="circular-btn">8</div>
            <div class="circular-btn">9</div>
            <div class="circular-btn">10</div>
            <div class="circular-btn">11</div>
            <div class="circular-btn">12</div>
            <div class="circular-btn">13</div>
            <div class="circular-btn">14</div>
            <div class="circular-btn">15</div>
            <div class="circular-btn">16</div>
            <div class="circular-btn">17</div>
            <div class="circular-btn">18</div>
            <div class="circular-btn">19</div>
            <div class="circular-btn">20</div>
            <div class="circular-btn">21</div>
            <div class="circular-btn">22</div>
            <div class="circular-btn">23</div>
            <div class="circular-btn">24</div>
            <div class="circular-btn">25</div>
            <div class="circular-btn">26</div>
            <div class="circular-btn">27</div>
            <div class="circular-btn">28</div>
            <div class="circular-btn">29</div>
            <div class="circular-btn">30</div>
        </div>
        <!-- 滚动提示Overlay -->
        <div class="scroll-overlay scroll-overlay-left"></div>
        <div class="scroll-overlay scroll-overlay-right"></div>
    </div>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            const scrollableDiv = document.getElementById('scrollableDiv');
            const scrollOverlayLeft = document.querySelector('.scroll-overlay-left');
            const scrollOverlayRight = document.querySelector('.scroll-overlay-right');

            // 初始加载时检查滚动状态
            updateOverlayVisibility();

            // 滚动时更新Overlay显示状态
            scrollableDiv.addEventListener('scroll', updateOverlayVisibility);
            // 窗口大小变化时重新检查
            window.addEventListener('resize', updateOverlayVisibility);

            function updateOverlayVisibility() {
                const scrollPosition = scrollableDiv.scrollLeft;
                const clientWidth = scrollableDiv.clientWidth;
                const scrollWidth = scrollableDiv.scrollWidth;

                // 左侧Overlay:滚动位置>0时显示,否则隐藏
                if (scrollPosition > 0) {
                    scrollOverlayLeft.classList.remove('hidden');
                } else {
                    scrollOverlayLeft.classList.add('hidden');
                }

                // 右侧Overlay:滚动到最右端时隐藏,否则显示
                if (scrollPosition + clientWidth >= scrollWidth - 1) { // 减1避免精度问题
                    scrollOverlayRight.classList.add('hidden');
                } else {
                    scrollOverlayRight.classList.remove('hidden');
                }
            }

            // 圆形按钮选中逻辑
            const circularButtons = document.querySelectorAll('.circular-btn');
            circularButtons.forEach(function(btn) {
                btn.addEventListener('click', function() {
                    circularButtons.forEach(function(b) {
                        b.classList.remove('selected');
                    });
                    this.classList.add('selected');
                });
            });
        });
    </script>
</body>
</html>

关键修改点说明:

  • DOM结构调整:新增.scroll-container-wrapper父容器,将Overlay从滚动内容容器中移出,让Overlay相对于父容器定位,实现固定在两侧的效果。
  • CSS优化:
    • 父容器设置position: relative,作为Overlay的定位基准
    • 修改Overlay的渐变背景为白色半透明,避免遮挡按钮内容
    • 用opacity过渡替代display切换,实现更平滑的显示/隐藏效果
  • JavaScript逻辑修复:
    • 修正滚动状态判断:右侧Overlay的隐藏条件改为scrollPosition + clientWidth >= scrollWidth,准确判断是否滚动到最右端
    • 新增窗口大小变化监听,确保窗口缩放时Overlay状态正确
    • 移除了错误的宽度动态计算逻辑,保持Overlay宽度固定,仅通过显示/隐藏反馈滚动状态

内容的提问来源于stack exchange,提问作者Rana Alharthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 16:34:56