如何通过mousedown>mousemove>mouseup操作纯JS实现多DIV选中
实现拖动选框选中元素的方案
要实现点击空白区域拖动鼠标选中元素的功能,不用range和selection(这类API主要用于文本选中场景),我们可以自己创建一个拖动选框,通过计算选框与目标元素的位置交集来判断选中状态。以下是完整实现代码:
const mainDiv = document.createElement("div"); mainDiv.style.width = "500px"; mainDiv.style.height = "500px"; mainDiv.style.border = "1px solid #eee"; // 加边框方便识别范围 mainDiv.style.position = "relative"; // 让内部绝对定位元素以它为基准 document.body.appendChild(mainDiv); const div1 = document.createElement("div"); div1.style.position = "absolute"; div1.style.top = `${50}px`; div1.style.left = `${50}px`; div1.style.width = "100px"; div1.style.height = "100px"; div1.style.background = "red"; mainDiv.appendChild(div1); const div2 = document.createElement("div"); div2.style.top = `${250}px`; div2.style.left = `${250}px`; div2.style.width = "100px"; div2.style.height = "100px"; div2.style.background = "green"; div2.style.position = "absolute"; mainDiv.appendChild(div2); // 存储所有可选中的元素 const selectableElements = [div1, div2]; // 拖动选框元素 let selectionBox = null; // 鼠标按下的起始坐标 let startX, startY; mainDiv.onmousedown = function(event) { // 仅点击mainDiv空白区域时触发(排除点击子元素的情况) if (event.target !== mainDiv) return; startX = event.clientX; startY = event.clientY; // 创建选框元素 selectionBox = document.createElement("div"); selectionBox.style.position = "fixed"; selectionBox.style.background = "rgba(100, 180, 255, 0.3)"; selectionBox.style.border = "1px solid #64b5f6"; selectionBox.style.pointerEvents = "none"; // 选框不干扰鼠标事件传递 selectionBox.style.zIndex = "9999"; document.body.appendChild(selectionBox); function onMouseMove(event) { // 计算选框的位置和尺寸,适配正反方向拖动 const currentX = event.clientX; const currentY = event.clientY; const top = Math.min(startY, currentY); const left = Math.min(startX, currentX); const width = Math.abs(currentX - startX); const height = Math.abs(currentY - startY); // 更新选框样式 selectionBox.style.top = `${top}px`; selectionBox.style.left = `${left}px`; selectionBox.style.width = `${width}px`; selectionBox.style.height = `${height}px`; // 检查每个元素是否被选框覆盖 selectableElements.forEach(el => { const elRect = el.getBoundingClientRect(); const boxRect = selectionBox.getBoundingClientRect(); // 矩形相交判断:只要两个矩形有重叠区域就算选中 const isIntersect = !( boxRect.right < elRect.left || boxRect.left > elRect.right || boxRect.bottom < elRect.top || boxRect.top > elRect.bottom ); // 给选中元素添加高亮样式 el.style.outline = isIntersect ? "2px solid #ffeb3b" : ""; }); } mainDiv.addEventListener('mousemove', onMouseMove); mainDiv.onmouseup = function() { // 清理选框 if (selectionBox) { document.body.removeChild(selectionBox); selectionBox = null; } // 移除鼠标移动监听 mainDiv.removeEventListener('mousemove', onMouseMove); // 收集并输出选中元素 const selectedElements = selectableElements.filter(el => el.style.outline); console.log("选中的元素:", selectedElements); // 可选:重置元素高亮样式 selectedElements.forEach(el => el.style.outline = ""); } }
核心逻辑说明:
- 选框创建与更新:鼠标按下时生成半透明选框,拖动过程中实时调整选框的位置和大小,适配正反方向拖动。
- 矩形交集判断:通过
getBoundingClientRect()获取元素和选框的位置信息,用反向排除法判断两者是否有重叠区域。 - 事件清理:鼠标松开后立即移除选框和
mousemove监听,避免内存泄漏和无效事件触发。
内容的提问来源于stack exchange,提问作者AntonAntonoff
相关产品推荐
相关产品推荐

