拖拽网格中的图片时如何实现页面上下滚动?
问题描述
需要实现网格底部的图片拖拽到顶部、顶部图片拖拽到底部的功能,但拖拽过程中页面无法上下滚动,尝试相关资源后仍未解决。
示例代码
<html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"/> <style> [draggable=true] { cursor: move; } .img-box { padding: 2px; aspect-ratio: 1/1; } .img-box > img { width: 100%; height: auto; } </style> </head> <body> <div class="container"> <div class="row"> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script> </body> </html>
解决方案
原生HTML拖拽API默认不会触发页面滚动,要实现拖拽时自动滚动页面,需要监听拖拽过程中的鼠标位置,判断是否靠近视口边缘后主动调整页面滚动位置,同时完善拖拽交换逻辑。
修改后的完整代码
<html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"/> <style> [draggable=true] { cursor: move; } .img-box { padding: 2px; aspect-ratio: 1/1; border: 2px solid transparent; transition: border-color 0.2s; } .img-box.drag-over { border-color: #007bff; } .img-box > img { width: 100%; height: auto; } </style> </head> <body> <div class="container"> <div class="row" id="imageRow"> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> <div draggable="true" class="col-3 img-box"> <img src="https://www.w3schools.com/w3images/underwater.jpg" /> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script> <script> let draggedElement = null; let scrollTimer = null; const scrollThreshold = 50; // 距离视口边缘50px触发滚动 const scrollSpeed = 10; // 滚动速度 // 拖拽开始时初始化 document.addEventListener('dragstart', (e) => { draggedElement = e.target.closest('.img-box'); draggedElement.classList.add('dragging'); // 启动滚动监听定时器 scrollTimer = setInterval(() => { const mouseY = e.clientY; const viewportHeight = window.innerHeight; // 靠近视口顶部,向上滚动 if (mouseY < scrollThreshold) { window.scrollBy(0, -scrollSpeed); } // 靠近视口底部,向下滚动 else if (mouseY > viewportHeight - scrollThreshold) { window.scrollBy(0, scrollSpeed); } }, 20); }); // 拖拽过程中处理元素位置交换 document.addEventListener('dragover', (e) => { e.preventDefault(); const target = e.target.closest('.img-box'); if (!target || target === draggedElement) return; // 计算插入位置:鼠标在目标元素上半部分则插在前面,下半部分插在后面 const rect = target.getBoundingClientRect(); const midpoint = rect.top + rect.height / 2; const insertAfter = e.clientY > midpoint; const parent = draggedElement.parentElement; if (insertAfter) { parent.insertBefore(draggedElement, target.nextSibling); } else { parent.insertBefore(draggedElement, target); } }); // 拖拽结束后清理 document.addEventListener('dragend', (e) => { draggedElement.classList.remove('dragging'); draggedElement = null; clearInterval(scrollTimer); scrollTimer = null; }); </script> </body> </html>
核心功能说明
- 自动滚动:拖拽时鼠标靠近视口上下边缘(50px阈值),页面会自动以设定速度滚动,方便将图片拖拽到超出当前视口的位置。
- 位置交换:拖拽过程中,根据鼠标在目标元素上的位置,自动调整被拖拽图片的插入位置,实现网格内任意位置的拖拽排序。
- 交互提示:添加了拖拽时的边框高亮效果,提升用户体验。
内容的提问来源于stack exchange,提问作者Rahul
相关产品推荐
相关产品推荐

