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

函数内无法设置元素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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 03:04:55