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

如何通过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 = "");
  }
}

核心逻辑说明:

  1. 选框创建与更新:鼠标按下时生成半透明选框,拖动过程中实时调整选框的位置和大小,适配正反方向拖动。
  2. 矩形交集判断:通过getBoundingClientRect()获取元素和选框的位置信息,用反向排除法判断两者是否有重叠区域。
  3. 事件清理:鼠标松开后立即移除选框和mousemove监听,避免内存泄漏和无效事件触发。

内容的提问来源于stack exchange,提问作者AntonAntonoff

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:53:28