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

如何实现自定义Div滚动条联动内容滚动(Windows95风格)

实现自定义滚动条与.canvastext区域的滚动同步

核心逻辑

通过监听自定义滚动条滑块的拖动事件,计算滑块在滚动条容器内的位置比例,同步设置.canvastext区域的scrollTop(垂直滚动)或scrollLeft(水平滚动)值,实现滚动联动。

完整可运行代码示例

直接套用即可适配你的Windows95 Paint风格页面:

<!DOCTYPE html>
<html>
<head>
    <style>
        /* Windows95 Paint窗口基础样式 */
        .paint-window {
            width: 650px;
            height: 450px;
            border: 2px solid #000;
            background: #c0c0c0;
            position: relative;
            overflow: hidden;
            box-shadow: 2px 2px 0 #808080, inset 1px 1px 0 #fff;
        }

        /* 内容区域 - .canvastext */
        .canvastext {
            width: calc(100% - 20px);
            height: 100%;
            overflow: hidden;
            background: #fff;
            padding: 8px;
            box-sizing: border-box;
        }

        /* 自定义垂直滚动条容器 */
        .custom-scrollbar {
            position: absolute;
            right: 0;
            top: 0;
            width: 18px;
            height: 100%;
            background: #c0c0c0;
            border-left: 1px solid #fff;
            box-shadow: inset -1px -1px 0 #808080;
        }

        /* 滚动条滑块(Windows95风格) */
        .scroll-thumb {
            width: 100%;
            height: 60px;
            background: #808080;
            border: 1px solid #fff;
            box-sizing: border-box;
            cursor: default;
            position: absolute;
            top: 0;
            box-shadow: 1px 1px 0 #000, inset 1px 1px 0 #c0c0c0;
        }
    </style>
</head>
<body>
    <div class="paint-window">
        <div class="canvastext" id="contentArea">
            <!-- 替换成你的实际内容 -->
            <p>Windows95 Paint 模拟内容行1</p>
            <p>Windows95 Paint 模拟内容行2</p>
            <p>Windows95 Paint 模拟内容行3</p>
            <p>Windows95 Paint 模拟内容行4</p>
            <p>Windows95 Paint 模拟内容行5</p>
            <p>Windows95 Paint 模拟内容行6</p>
            <p>Windows95 Paint 模拟内容行7</p>
            <p>Windows95 Paint 模拟内容行8</p>
            <p>Windows95 Paint 模拟内容行9</p>
            <p>Windows95 Paint 模拟内容行10</p>
            <p>Windows95 Paint 模拟内容行11</p>
            <p>Windows95 Paint 模拟内容行12</p>
            <p>Windows95 Paint 模拟内容行13</p>
            <p>Windows95 Paint 模拟内容行14</p>
            <p>Windows95 Paint 模拟内容行15</p>
            <p>Windows95 Paint 模拟内容行16</p>
            <p>Windows95 Paint 模拟内容行17</p>
            <p>Windows95 Paint 模拟内容行18</p>
            <p>Windows95 Paint 模拟内容行19</p>
            <p>Windows95 Paint 模拟内容行20</p>
        </div>
        <div class="custom-scrollbar">
            <div class="scroll-thumb" id="scrollThumb"></div>
        </div>
    </div>

    <script>
        // 获取页面元素
        const contentArea = document.getElementById('contentArea');
        const scrollThumb = document.getElementById('scrollThumb');
        const scrollbarContainer = scrollThumb.parentElement;

        // 初始化滑块高度:根据内容长度自动适配
        function initScrollThumbSize() {
            const totalContentHeight = contentArea.scrollHeight;
            const visibleContentHeight = contentArea.clientHeight;
            // 滑块高度比例 = 可视区域高度 / 内容总高度
            const thumbHeightRatio = visibleContentHeight / totalContentHeight;
            // 限制滑块最小高度,避免过窄无法拖动
            scrollThumb.style.height = `${Math.max(40, thumbHeightRatio * scrollbarContainer.clientHeight)}px`;
        }

        // 滑块拖动逻辑
        scrollThumb.addEventListener('mousedown', startDrag);

        function startDrag(e) {
            e.preventDefault();
            // 记录鼠标按下时,相对于滑块顶部的偏移量
            const mouseOffsetY = e.clientY - scrollThumb.offsetTop;
            
            // 添加全局鼠标移动/松开监听
            document.addEventListener('mousemove', handleDrag);
            document.addEventListener('mouseup', stopDrag);

            function handleDrag(e) {
                // 计算滑块的新位置
                let newThumbTop = e.clientY - mouseOffsetY;
                // 限制滑块在滚动条容器范围内
                const maxThumbTop = scrollbarContainer.clientHeight - scrollThumb.offsetHeight;
                newThumbTop = Math.max(0, Math.min(maxThumbTop, newThumbTop));
                scrollThumb.style.top = `${newThumbTop}px`;

                // 计算滚动比例,同步内容区域滚动
                const scrollRatio = newThumbTop / maxThumbTop;
                contentArea.scrollTop = scrollRatio * (contentArea.scrollHeight - contentArea.clientHeight);
            }

            function stopDrag() {
                // 移除全局监听,结束拖动
                document.removeEventListener('mousemove', handleDrag);
                document.removeEventListener('mouseup', stopDrag);
            }
        }

        // 页面加载时初始化滑块
        window.addEventListener('load', initScrollThumbSize);
        // 若内容动态更新,需调用initScrollThumbSize()重新计算滑块高度
    </script>
</body>
</html>

关键细节说明

  1. 滑块高度自适应:initScrollThumbSize函数会根据内容总高度和可视区域高度,自动计算滑块的合理高度,内容越长滑块越短,符合原生滚动条的逻辑。
  2. 拖动边界限制:拖动时会限制滑块只能在滚动条容器内移动,避免滑块超出可视范围。
  3. 滚动比例同步:通过滑块位置比例,精准同步内容区域的滚动距离,保证拖动体验和原生滚动一致。
  4. 水平滚动适配:如果需要实现水平滚动,只需把代码中所有scrollTop替换为scrollLeft,clientHeight替换为clientWidth,offsetTop替换为offsetLeft,clientY替换为clientX即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:21