函数内无法设置元素scrollTop,但scrollLeft可正常设置
拖拽滚动时scrollTop无效的问题修复
你的代码里有个明显的笔误,导致touch事件下的Y坐标计算完全错误,进而让scrollTop的设置看起来无效:
在dragMouseDown函数中,初始化startY时,你错误地使用了e.targetTouches[0].pageX(X轴坐标)而非pageY(Y轴坐标):
startY = (e.clientY || e.targetTouches[0].pageX); // 这里的pageX是错误的
这会导致后续elementDrag中计算的dy值完全不符合预期,进而让scrollTop的调整逻辑失效。
另外,你使用了全局变量startX、startY、dx、dy,这可能会导致多次拖拽时的变量冲突,最好将它们改为函数内部的局部变量。
修正后的JavaScript代码
dragElement(document.getElementById("drag-wrapper")); let pageDraggable = true; // 声明为局部变量,避免全局污染 function dragElement(elmnt) { let startX, startY; // 把变量放在函数内部,避免全局冲突 // drag from anywhere in the element elmnt.addEventListener('mousedown', dragMouseDown); elmnt.addEventListener('touchstart', dragMouseDown); function dragMouseDown(e) { if (pageDraggable) { e = e || window.event; e.preventDefault(); // 统一坐标获取方式,鼠标用clientX/clientY,触摸用targetTouches[0].clientX/clientY const clientX = e.clientX || e.targetTouches[0].clientX; const clientY = e.clientY || e.targetTouches[0].clientY; // get the mouse cursor position at startup: startX = clientX; startY = clientY; document.addEventListener('mouseup', closeDragElement); document.addEventListener('touchend', closeDragElement); // call a function whenever the cursor moves: document.addEventListener('touchmove', elementDrag); document.addEventListener('mousemove', elementDrag); } } function elementDrag(e) { if (pageDraggable) { e = e || window.event; e.preventDefault(); // 统一坐标获取 const clientX = e.clientX || e.targetTouches[0].clientX; const clientY = e.clientY || e.targetTouches[0].clientY; // calculate the change in cursor position: const dx = clientX - startX; const dy = clientY - startY; // set the element's new position: elmnt.scrollTop = elmnt.scrollTop - (dy / 3); elmnt.scrollLeft = elmnt.scrollLeft - (dx / 3); // 更新start坐标,让拖拽更流畅(可选,避免累积误差) startX = clientX; startY = clientY; } } function closeDragElement() { // stop moving when button/touch is over document.removeEventListener('mouseup', closeDragElement); document.removeEventListener('touchend', closeDragElement); document.removeEventListener('touchmove', elementDrag); document.removeEventListener('mousemove', elementDrag); } }
额外说明
- 修正了touch事件中Y坐标的获取错误,这是导致scrollTop无效的核心原因
- 将所有相关变量改为函数内部的局部变量,避免全局变量污染和多次拖拽时的冲突
- 统一了鼠标和触摸事件的坐标获取方式,使用
clientX/clientY保持一致,减少坐标计算误差 - 可选:在
elementDrag中每次更新startX和startY,可以让拖拽过程更流畅,避免累积误差
内容的提问来源于stack exchange,提问作者codecreature
相关产品推荐
相关产品推荐

