js 仿window拉选框 / 选中文件

目录

1. window效果

2. 实现思路

1. 元素分析

2. 思路分析

3. 实现拉选框

1. 代码

2. 实现效果 

4. 实现元素选中效果 

1. 获取所有元素的我们需要的属性

2. 判断是否选中了某个元素并改变他的颜色

3. 实现效果

5. 完整代码

 6. 总结


1. window效果

 这里是window11的效果

2. 实现思路

1. 元素分析

1. 只要包含在拉选框内的都会被选中,这样就需要获取拉选框的x,y,height,width和元素的x,y,widht,height来进行组合判断。

2. 获取元素的所需要的属性可以使用getBoundingClientRect方法来获取这个矩形的属性值

3. 图标元素的x,y就等于getBoundingClientRect().x ,getBoundingClientRect().x。widht和height相同的原理

2. 思路分析

1. 拉选框是一个绝对定位的元素,我这里使用div

// css
.box{
  position: absolute;
  background-color: rgba(13, 153, 255, 0.3);
  border: 1px solid rgb(13, 153, 255);
}
// js
const box = document.createElement('div');
box.className = 'box';

2. 给拉选框添加事件

1.mousedown  向body添加box元素并添加move,up事件

function mouseDown(e){
  box.style.width = '0px';
  box.style.height = '0px';
  body.append(box);
  // initPosition 记录初始坐标
  initPosition.x = e.clientX;
  initPosition.y = e.clientY;
  box.style.top = e.clientY + 'px';
  box.style.left = e.clientX + 'px';

  body.addEventListener('mousemove', mouseMove);
  body.addEventListener('mouseup', mouseUp);
}

2.mousemove 初始坐标为定点想象一个象限轴,可以有四个方向移动

function mouseMove(e){
  const {x,y} = initPosition;
  // 设置移动位置
  const moveX = e.clientX;
  const moveY = e.clientY;
  // 计算移动后对应元素宽高
  const width = Math.abs(x - moveX);
  const height = Math.abs(y - moveY);
  // 判断方向及顶点位置
  if(moveX > x && moveY > y){ // 4象限
    box.style.left = x + 'px';
    box.style.top = y + 'px';
  }else if(y > moveY && x < moveX){ // 1象限
    box.style.top = moveY + 'px';
    box.style.left = x + 'px';
  }else if(moveX < x && moveY > y){ // 3象限
    box.style.left = moveX + 'px';
    box.style.top = y + 'px';
  }else if(moveY < y && moveX < x){ // 2象限
    box.style.top = moveY + 'px';
    box.style.left = moveX + 'px';
  }
  requestAnimationFrame(() => {
    box.style.width = width + 'px';
    box.style.height = height + 'px';
  })
}

3.mouseup 鼠标抬起时应该移除box元素和move,up事件

function mouseUp(){
  body.removeChild(box);
  body.removeEventListener('mousemove', mouseMove);
  body.removeEventListener('mouseup', mouseUp);
}

3. 实现拉选框

1. 代码

const body = document.querySelector('body');
const box = document.createElement('div');
box.className = 'box';
body.addEventListener('mousedown', mouseDown);
function mouseDown(e){
  box.style.width = '0px';
  box.style.height = '0px';
  selectArr = [];
  body.append(box);
  initPosition.x = e.clientX;
  initPosition.y = e.clientY;
  box.style.top = e.clientY + 'px';
  box.style.left = e.clientX + 'px';
  body.addEventListener('mousemove', mouseMove);
  body.addEventListener('mouseup', mouseUp);
}
function mouseMove(e){
  const {x,y} = initPosition;
  // 设置移动位置
  const moveX = e.clientX;
  const moveY = e.clientY;
  // 计算移动后对应元素宽高
  const width = Math.abs(x - moveX);
  const height = Math.abs(y - moveY);
  // 判断方向及顶点位置
  if(moveX > x && moveY > y){ // 4
    box.style.left = x + 'px';
    box.style.top = y + 'px';
  }else if(y > moveY && x < moveX){ // 1
    box.style.top = moveY + 'px';
    box.style.left = x + 'px';
  }else if(moveX < x && moveY > y){ // 3
    box.style.left = moveX + 'px';
    box.style.top = y + 'px';
  }else if(moveY < y && moveX < x){ // 2
    box.style.top = moveY + 'px';
    box.style.left = moveX + 'px';
  }
  requestAnimationFrame(() => {
    box.style.width = width + 'px';
    box.style.height = height + 'px';
    // isSelect();
  })
}
function mouseUp(){
  body.removeChild(box);
  body.removeEventListener('mousemove', mouseMove);
  body.removeEventListener('mouseup', mouseUp);
}

2. 实现效果 

4. 实现元素选中效果 

1. 获取所有元素的我们需要的属性

function initSelectBox(){
  const domArr = document.querySelectorAll('.select');
  for(let i = 0; i < domArr.length; i++){
    const item = domArr[i];
    const obj = {
      dom:item,
      x:item.getBoundingClientRect().left,
      y:item.getBoundingClientRect().top,
      width:item.getBoundingClientRect().width,
      height:item.getBoundingClientRect().height,
    }
    select.push(obj);
  }
}

2. 判断是否选中了某个元素并改变他的颜色

function isSelect(){
  const {width, height, left, top} = box.getBoundingClientRect();
  for(let i = 0; i < select.length; i++){
    const item = select[i];
    if(
      left < item.x + item.width &&
      item.x < left + width &&
      top < item.y + item.height &&
      item.y < top + height
    ){
      if(!selectArr.find(items => items === item)){ // 如果selectArr里有item元素则不push
        selectArr.push(item);
      }
      item.dom.style.backgroundColor = 'rgba(13, 153, 255, 0.3)';
    }else{
      if(selectArr.find(items => items === item)){ // 如果能找到item元素则从selectArr里删除该元素
        selectArr.splice(selectArr.findIndex(items => items === item), 1);
      }
      item.dom.style.backgroundColor = 'rgba(122, 145, 161)';
    }
  }
}

3. 实现效果

5. 完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    body{
      width: 100vw;
      height: 100vh;
      position: relative;
    }
    .box{
      position: absolute;
      background-color: rgba(13, 153, 255, 0.3);
      border: 1px solid rgb(13, 153, 255);
    }
    .container{
      width: 100vw;
      height: 100vh;
    }
    .item{
      display: flex;
    }
    .select{
      cursor: pointer;
      margin: 100px;
      width: 100px;
      height: 100px;
      min-width: 100px;
      min-height: 100px;
      background-color: rgba(122, 145, 161, 1);
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="item">
      <div class="select"></div>
      <div class="select"></div>
      <div class="select"></div>
      <div class="select"></div>
    </div>
    <div class="item">
      <div class="select"></div>
      <div class="select"></div>
      <div class="select"></div>
      <div class="select"></div>
    </div>
  </div>
  <script>
    const body = document.querySelector('body');
    const box = document.createElement('div');
    box.className = 'box';
    const select = [];
    let selectArr = []
    const initPosition = {
      x: 0,
      y: 0
    }
    initSelectBox();
    function initSelectBox(){
      const domArr = document.querySelectorAll('.select');
      for(let i = 0; i < domArr.length; i++){
        const item = domArr[i];
        const obj = {
          dom:item,
          x:item.getBoundingClientRect().left,
          y:item.getBoundingClientRect().top,
          width:item.getBoundingClientRect().width,
          height:item.getBoundingClientRect().height,
        }
        select.push(obj);
      }
    }
    body.addEventListener('mousedown', mouseDown);
    function mouseDown(e){
      box.style.width = '0px';
      box.style.height = '0px';
      selectArr = [];
      body.append(box);
      initPosition.x = e.clientX;
      initPosition.y = e.clientY;
      box.style.top = e.clientY + 'px';
      box.style.left = e.clientX + 'px';

      body.addEventListener('mousemove', mouseMove);
      body.addEventListener('mouseup', mouseUp);
    }
    function mouseMove(e){
      const {x,y} = initPosition;
      // 设置移动位置
      const moveX = e.clientX;
      const moveY = e.clientY;
      // 计算移动后对应元素宽高
      const width = Math.abs(x - moveX);
      const height = Math.abs(y - moveY);
      // 判断方向及顶点位置
      if(moveX > x && moveY > y){ // 4
        box.style.left = x + 'px';
        box.style.top = y + 'px';
      }else if(y > moveY && x < moveX){ // 1
        box.style.top = moveY + 'px';
        box.style.left = x + 'px';
      }else if(moveX < x && moveY > y){ // 3
        box.style.left = moveX + 'px';
        box.style.top = y + 'px';
      }else if(moveY < y && moveX < x){ // 2
        box.style.top = moveY + 'px';
        box.style.left = moveX + 'px';
      }
      requestAnimationFrame(() => {
        box.style.width = width + 'px';
        box.style.height = height + 'px';
        isSelect();
      })
    }
    function mouseUp(){
      console.log(selectArr)
      body.removeChild(box);
      body.removeEventListener('mousemove', mouseMove);
      body.removeEventListener('mouseup', mouseUp);
    }
    // 判断box是否选中元素
    function isSelect(){
      const {width, height, left, top} = box.getBoundingClientRect();
      for(let i = 0; i < select.length; i++){
        const item = select[i];
        if(
          left < item.x + item.width &&
          item.x < left + width &&
          top < item.y + item.height &&
          item.y < top + height
        ){
          if(!selectArr.find(items => items === item)){
            selectArr.push(item);
          }
          item.dom.style.backgroundColor = 'rgba(13, 153, 255, 0.3)';
        }else{
          if(selectArr.find(items => items === item)){
            selectArr.splice(selectArr.findIndex(items => items === item), 1);
          }
          item.dom.style.backgroundColor = 'rgba(122, 145, 161)';
        }
      }
    }

  </script>
</body>
</html>

 6. 总结

大概的实现思路就是这样,网络上也会有更优的方法,我写的还一点小bug如果大家发现并能修复可以告诉博主,感谢!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值