如何实现自定义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>
关键细节说明
- 滑块高度自适应:
initScrollThumbSize函数会根据内容总高度和可视区域高度,自动计算滑块的合理高度,内容越长滑块越短,符合原生滚动条的逻辑。 - 拖动边界限制:拖动时会限制滑块只能在滚动条容器内移动,避免滑块超出可视范围。
- 滚动比例同步:通过滑块位置比例,精准同步内容区域的滚动距离,保证拖动体验和原生滚动一致。
- 水平滚动适配:如果需要实现水平滚动,只需把代码中所有
scrollTop替换为scrollLeft,clientHeight替换为clientWidth,offsetTop替换为offsetLeft,clientY替换为clientX即可。
内容的提问来源于stack exchange,提问作者Luna
相关产品推荐
相关产品推荐

