需求:修改Dragbar功能使其仅在截图区域滑动而非联动双面板
实现顶部截图区域独立滑动的Dragbar方案
核心思路
将dragbar的作用范围完全限制在顶部截图容器内,与下方文章面板的布局解绑,具体步骤:
- 拆分布局:把顶部截图对比区和下方文章对比区做独立结构,各自维持自身布局逻辑
- 隔离事件:仅监听dragbar在顶部截图容器内的鼠标/触摸事件,拖动时只调整截图区的遮罩或分割显示,不修改文章面板的宽度或位置
- 视觉同步(可选):如果需要让文章区和截图区有联动视觉效果,仅做样式同步,不改变面板的布局属性
代码实现示例
HTML结构
<div class="compare-container"> <!-- 顶部截图对比区 --> <div class="screenshot-box"> <img src="left-shot.jpg" class="shot left" alt="左侧截图"> <img src="right-shot.jpg" class="shot right" alt="右侧截图"> <div class="dragbar" id="shotDragbar"></div> <div class="split-mask" id="shotMask"></div> </div> <!-- 下方文章对比区 --> <div class="articles-box"> <div class="article left"> <!-- 左侧文章内容 --> </div> <div class="article right"> <!-- 右侧文章内容 --> </div> </div> </div>
CSS样式
.compare-container { width: 100%; max-width: 1200px; margin: 0 auto; } /* 顶部截图区样式 */ .screenshot-box { position: relative; width: 100%; height: 320px; overflow: hidden; margin-bottom: 24px; } .shot { position: absolute; top: 0; width: 100%; height: 100%; object-fit: contain; } .shot.left { z-index: 1; } .shot.right { z-index: 0; } #shotMask { position: absolute; top: 0; left: 50%; width: 50%; height: 100%; background: #fff; z-index: 2; } .dragbar { position: absolute; top: 0; left: 50%; width: 4px; height: 100%; background: #ff5722; cursor: ew-resize; z-index: 3; } /* 下方文章区样式 */ .articles-box { display: flex; gap: 24px; } .article { flex: 1; padding: 16px; border: 1px solid #e0e0e0; border-radius: 4px; }
JavaScript逻辑
const dragbar = document.getElementById('shotDragbar'); const mask = document.getElementById('shotMask'); const shotBox = document.querySelector('.screenshot-box'); let isDragging = false; let startX = 0; let initMaskWidth = 0; // 鼠标拖动逻辑 dragbar.addEventListener('mousedown', (e) => { isDragging = true; startX = e.clientX; initMaskWidth = parseFloat(getComputedStyle(mask).width); document.body.style.userSelect = 'none'; // 防止拖动时选中文字 }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; const boxWidth = shotBox.offsetWidth; const offset = e.clientX - startX; // 计算新的遮罩宽度,限制在0-100%之间 let newWidth = initMaskWidth + (offset / boxWidth) * 100; newWidth = Math.max(0, Math.min(100, newWidth)); // 更新遮罩和dragbar位置 mask.style.width = `${newWidth}%`; dragbar.style.left = `${100 - newWidth}%`; }); document.addEventListener('mouseup', () => { isDragging = false; document.body.style.userSelect = ''; }); // 移动端触摸适配 dragbar.addEventListener('touchstart', (e) => { isDragging = true; startX = e.touches[0].clientX; initMaskWidth = parseFloat(getComputedStyle(mask).width); }); document.addEventListener('touchmove', (e) => { if (!isDragging) return; e.preventDefault(); // 阻止页面滚动 const boxWidth = shotBox.offsetWidth; const offset = e.touches[0].clientX - startX; let newWidth = initMaskWidth + (offset / boxWidth) * 100; newWidth = Math.max(0, Math.min(100, newWidth)); mask.style.width = `${newWidth}%`; dragbar.style.left = `${100 - newWidth}%`; }); document.addEventListener('touchend', () => { isDragging = false; });
关键说明
- 顶部截图区通过遮罩层(
split-mask)实现左右截图的切换显示,dragbar拖动时仅修改遮罩宽度和自身位置,完全不影响下方文章面板的布局 - 文章面板采用
flex:1实现平分宽度,始终保持并排状态,不会被dragbar操作干扰 - 加入了触摸事件适配,支持移动端操作
- 限制了dragbar的拖动范围,确保不会超出截图容器边界
内容的提问来源于stack exchange,提问作者user25017272
相关产品推荐
相关产品推荐

