jQuery实现元素自身拖拽横向滚动时scrollLeft异常问题求解
问题根因
你改动后滚动速度过快的核心原因是没有固定滚动计算的基准值:每次mousemove触发时,你都在当前scrollLeft的基础上叠加「鼠标按下初始位置到当前位置的总偏移量」,相当于每触发一次mousemove就重复累加一次总偏移,自然会出现滚动速度远超鼠标移动速度的问题。
修复方案
推荐使用「固定初始基准值」的实现方式,逻辑更稳定无累积误差,同时优化事件绑定逻辑避免全局误触发:
// 存储拖拽状态 let isDragging = false; let startX = 0; let startScrollLeft = 0; const $slider = $('.box02-planos'); // 绑定容器的鼠标按下事件 $slider.on('mousedown', function(e) { isDragging = true; // 记录鼠标按下时的初始坐标 startX = e.pageX; // 记录此时容器的scrollLeft初始值 startScrollLeft = $(this).scrollLeft(); // 修改鼠标样式,阻止默认选中文本行为 $(this).css('cursor', 'grabbing'); e.preventDefault(); }); // 全局监听鼠标移动 $(document).on('mousemove', function(e) { if (!isDragging) return; // 直接用初始值计算,不需要累加当前scrollLeft,滚动比例和鼠标移动1:1匹配 $slider.scrollLeft(startScrollLeft + (startX - e.pageX)); }); // 全局监听鼠标抬起/离开窗口,结束拖拽 $(document).on('mouseup mouseleave', function() { isDragging = false; $slider.css('cursor', 'grab'); });
配合对应的CSS优化交互体验:
.box02-planos { overflow-x: hidden; cursor: grab; /* 禁止选中文本,避免拖拽时选中容器内内容 */ user-select: none; }
最小改动方案(保留原有逻辑)
如果不想调整整体结构,只需要在每次更新scrollLeft后,同步更新clickX为当前鼠标坐标,让下一次计算的是两次移动之间的增量偏移即可:
updateScrollPos = function(e) { if(box02_planos_hover){ const offset = clickX - e.pageX; $(box02_planos).scrollLeft($(box02_planos).scrollLeft() + offset); // 新增这行更新基准坐标 clickX = e.pageX; } }
内容的提问来源于stack exchange,提问作者Helton Barros
相关产品推荐
相关产品推荐

