当前位置:首页 > JavaScript

js实现框选

2026-04-05 06:27:45JavaScript

实现框选的基本思路

框选功能通常涉及监听鼠标事件,记录起始和结束位置,动态绘制选框。以下是具体实现方法:

监听鼠标事件

在需要框选的容器上绑定mousedownmousemovemouseup事件:

js实现框选

const container = document.getElementById('selectable-area');
let isSelecting = false;
let startX, startY;

container.addEventListener('mousedown', (e) => {
  isSelecting = true;
  startX = e.clientX;
  startY = e.clientY;
});

document.addEventListener('mousemove', (e) => {
  if (!isSelecting) return;
  // 更新选框位置和尺寸
});

document.addEventListener('mouseup', () => {
  isSelecting = false;
  // 清除选框或执行选中逻辑
});

动态绘制选框

创建绝对定位的div作为选框元素,并根据鼠标位置调整其样式:

js实现框选

const selectionBox = document.createElement('div');
selectionBox.style.position = 'absolute';
selectionBox.style.border = '2px dashed #000';
selectionBox.style.backgroundColor = 'rgba(0, 0, 255, 0.1)';
document.body.appendChild(selectionBox);

// 在mousemove事件中更新选框
const currentX = e.clientX;
const currentY = e.clientY;
selectionBox.style.left = Math.min(startX, currentX) + 'px';
selectionBox.style.top = Math.min(startY, currentY) + 'px';
selectionBox.style.width = Math.abs(currentX - startX) + 'px';
selectionBox.style.height = Math.abs(currentY - startY) + 'px';

检测元素碰撞

判断目标元素是否在选框区域内:

function isElementInSelection(element, selectionBox) {
  const elementRect = element.getBoundingClientRect();
  const selectionRect = selectionBox.getBoundingClientRect();

  return !(
    elementRect.right < selectionRect.left ||
    elementRect.left > selectionRect.right ||
    elementRect.bottom < selectionRect.top ||
    elementRect.top > selectionRect.bottom
  );
}

// 遍历所有可选元素
document.querySelectorAll('.selectable-item').forEach(item => {
  if (isElementInSelection(item, selectionBox)) {
    item.classList.add('selected');
  }
});

清除选框状态

鼠标释放时移除选框元素或重置状态:

document.addEventListener('mouseup', () => {
  isSelecting = false;
  selectionBox.remove();
  // 或重置选框尺寸
  selectionBox.style.width = '0';
  selectionBox.style.height = '0';
});

完整示例代码

document.addEventListener('DOMContentLoaded', () => {
  const container = document.getElementById('selectable-area');
  const selectionBox = document.createElement('div');
  let isSelecting = false;
  let startX, startY;

  selectionBox.style.position = 'absolute';
  selectionBox.style.border = '2px dashed #000';
  selectionBox.style.backgroundColor = 'rgba(0, 0, 255, 0.1)';
  selectionBox.style.display = 'none';
  document.body.appendChild(selectionBox);

  container.addEventListener('mousedown', (e) => {
    isSelecting = true;
    startX = e.clientX;
    startY = e.clientY;
    selectionBox.style.left = `${startX}px`;
    selectionBox.style.top = `${startY}px`;
    selectionBox.style.width = '0';
    selectionBox.style.height = '0';
    selectionBox.style.display = 'block';
  });

  document.addEventListener('mousemove', (e) => {
    if (!isSelecting) return;

    const currentX = e.clientX;
    const currentY = e.clientY;

    selectionBox.style.left = Math.min(startX, currentX) + 'px';
    selectionBox.style.top = Math.min(startY, currentY) + 'px';
    selectionBox.style.width = Math.abs(currentX - startX) + 'px';
    selectionBox.style.height = Math.abs(currentY - startY) + 'px';
  });

  document.addEventListener('mouseup', () => {
    if (!isSelecting) return;
    isSelecting = false;
    selectionBox.style.display = 'none';

    document.querySelectorAll('.selectable-item').forEach(item => {
      const elementRect = item.getBoundingClientRect();
      const selectionRect = selectionBox.getBoundingClientRect();

      if (!(
        elementRect.right < selectionRect.left ||
        elementRect.left > selectionRect.right ||
        elementRect.bottom < selectionRect.top ||
        elementRect.top > selectionRect.bottom
      )) {
        item.classList.toggle('selected');
      }
    });
  });
});

注意事项

  • 确保选框元素的z-index高于其他内容
  • 考虑滚动偏移时需调整坐标计算
  • 移动端需要额外处理触摸事件
  • 性能优化:对于大量可选元素,可以使用空间分区算法提高检测效率

标签: js
分享给朋友:

相关文章

js实现分页

js实现分页

分页的基本实现思路 在JavaScript中实现分页功能通常需要结合前端和后端逻辑。前端负责渲染分页控件和处理用户交互,后端负责提供分页数据。 前端分页实现 纯前端分页适用于数据量较小的情况,可以直…

js实现继承

js实现继承

原型链继承 通过将子类的原型指向父类的实例实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Parent…

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Par…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…

js实现驼峰

js实现驼峰

实现驼峰命名的几种方法 使用正则表达式和字符串替换 通过正则表达式匹配字符串中的特定模式(如下划线或短横线),并将其后的字母转换为大写,同时移除分隔符。 function toCamelCase(s…

js实现选题

js实现选题

实现选题功能的JavaScript方法 基础实现方案 使用数组存储选项,通过随机索引选取: const options = ['选项A', '选项B', '选项C', '选项D']; const r…