拖拽同时支持Y轴滚动
一.父容器+window
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>拖拽自动滚动测试</title><style>#parent {max-height: 2000px; /* 远超屏幕高度 */overflow-y: auto; /* 出现滚动条 */border: 1px solid #ccc;position: relative;margin: 50px auto;width: 80%;}.child {height: 50px;background: lightblue;margin: 5px;display: flex;align-items: center;justify-content: center;cursor: move; /* 鼠标样式 */}</style>
</head>
<body><div id="parent"><div class="child" draggable="true">Item 1</div><div class="child" draggable="true">Item 2</div><div class="child" draggable="true">Item 3</div><div class="child" draggable="true">Item 4</div><div class="child" draggable="true">Item 5</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><div class="child" draggable="true">Item 6</div><!-- 可以继续添加更多子项 -->
</div><script>const parent = document.getElementById('parent');// 监听整个文档的 dragover 事件(因为拖拽过程中鼠标可能移出父容器)document.addEventListener('dragover', (e) => {// 必须阻止默认行为,否则某些浏览器可能不允许拖拽e.preventDefault();// 获取父容器的位置信息const rect = parent.getBoundingClientRect();// 获取当前鼠标 Y 坐标const mouseY = e.clientY;// 定义触发滚动的阈值(距离边缘多少像素时开始滚动)const scrollThreshold = 100;// 定义每次滚动的像素数const scrollSpeed = 20;// 计算鼠标在父容器内的相对位置// 注意:rect.top 是父容器顶部相对于视口的位置// mouseY 是鼠标相对于视口的位置// 所以鼠标在父容器内的相对 Y 坐标是:mouseY - rect.top// mouseY - rect.top 计算鼠标在父容器内的相对位置,这样无论父容器是否滚动,都能正确判断鼠标是否接近父容器的边缘。const mouseYInParent = mouseY - rect.top;console.log("mouseYInParent:",mouseYInParent)let isParentScroll = false;// 判断是否需要滚动父容器if (mouseYInParent < scrollThreshold) {isParentScroll = true;// 靠近父容器顶部,向上滚动parent.scrollTop -= scrollSpeed;} else if (mouseYInParent > rect.height - scrollThreshold) {isParentScroll = true;// 靠近父容器底部,向下滚动parent.scrollTop += scrollSpeed;}if(isParentScroll){console.log("父容器在滚动----------------------------父容器在滚动")}let isWindowScroll = false;// 判断是否需要滚动页面(当父容器本身已经接近页面边缘时)// 如果鼠标靠近屏幕底部,且父容器已经滚动到页面底部 → 滚动页面if (mouseY > window.innerHeight - scrollThreshold) {isWindowScroll = true;window.scrollBy(0, scrollSpeed); // 向下滚动页面}// 如果鼠标靠近屏幕顶部,且父容器顶部已经到达视口顶部 → 滚动页面// 如果父容器顶部已经到达视口顶部(rect.top <= 0),说明父容器不能再向上滚动(rect.top 已经包含 margin等值)// 此时如果鼠标靠近屏幕顶部(mouseY < scrollThreshold),就可以触发页面向上滚动;if (mouseY < scrollThreshold && rect.top <= 0) {isWindowScroll = true;window.scrollBy(0, -scrollSpeed); // 向上滚动页面}if(isWindowScroll){console.log("window在滚动----------------------------window在滚动")}});
</script>
</body>
</html>