vue类似与window上多选文件

前言:因为这是个文件管理系统,替代用户原来的ftp系统。
用户在原来的系统里面习惯的的操作要在新系统中体现,特别是鼠标框选之类的操作。

效果图:
在这里插入图片描述
第一个是框选效果,第二个是按住CTRL后鼠标左键选择的效果。
代码是纯js写的,ps:主要是没找到合适的vue框选效果
html代码:
在这里插入图片描述

一定要看好层级关系
第一个红框中右两个事件,mouseup鼠标抬起事件,mousedown.left是鼠标左键点击事件
第二个红框中的style必须设置,这个div是与框选效果框同级

css代码

.rectangular{
    background-color: rgba(235, 239, 243,0.45);
    position: fixed;
    border: 1px solid rgba(24, 135, 243,1);
    z-index: 20;
}

js代码

有四个方法

//以下四个方法都是关于多选的
//按住ctrl多选
keyDownCtrl(event, item) {
    //获取点击对象
    let div = event.currentTarget;
    let orginClassName = div.className;

    this.isRightClickCtrl = true;
    if (this.selectIdList.indexOf(item.fileId) == -1) {
        this.selectIdList.push(item.fileId);
        div.className = orginClassName + " " + "ctrlClick"
        div.style = 'border: 1px solid rgba(24, 135, 243, 0.5)'
    }
},
//还原样式
setFileDivClass() {
    let files = document.getElementsByName("file");
    for (let i = 0; i < files.length; i++) {
        const file = files[i];
        file.style="";
        file.className = this.selectDivClassName;
    }
},

//鼠标左键按下方法
onmousedownClick(event) {
    this.isRightClick = true;
    this.start_x = event.clientX;
    this.start_y = event.clientY;
    console.log(" this.start_x="+ this.start_x);
    console.log(" this.start_y="+ this.start_y);
    let that=this;
    
  document.onmousemove=function (event) {
      let end_x=event.clientX;
      let end_y=event.clientY;
      let divElement=document.getElementById("rectangular");
      divElement.style.display='block'
      divElement.className='rectangular';
      //从左往右
     // 画矩形
      if(that.start_x<end_x){
          divElement.style.width=(end_x-that.start_x)+"px";
          divElement.style.height=(that.start_y>end_y>0?(that.start_y-end_y):(end_y-that.start_y))+"px";
          divElement.style.left=that.start_x+"px";
          divElement.style.right=end_x+"px";
          //从下往上
          if(that.start_y>end_y){
              divElement.style.top=end_y+"px";
              divElement.style.bottom=that.start_y+"px";
          }else{
              divElement.style.top=that.start_y+"px";
              divElement.style.bottom=end_y+"px";
          }
      }else{
          divElement.style.width=(that.start_x-end_x)+"px";
          divElement.style.height=(that.start_y>end_y>0?(that.start_y-end_y):(end_y-that.start_y))+"px";
          divElement.style.left=end_x+"px";
          divElement.style.right=that.start_x+"px";
          //从下往上
          if(that.start_y>end_y){
              divElement.style.top=end_y+"px";
              divElement.style.bottom=that.start_y+"px";
          }else{
              divElement.style.top=that.start_y+"px";
              divElement.style.bottom=end_y+"px";
          }
      }
  }
  document.onmouseup=function () {
      //禁用鼠标移动时间
      document.onmousemove=function () {
          return false;
      }
      // 移动样式清空
      let divElement=document.getElementById("rectangular");
      divElement.style.display='none';
  }
},
//鼠标左键抬起方法
handMouseUp: function (event) {

    this.end_x = event.clientX;
    this.end_y = event.clientY;
    console.log(" this.end_x=" + this.end_x);
    console.log(" this.end_y=" + this.end_y);
    //核心内容,根据你的鼠标移动矩形区域来判断div是否在里面
    this.isRightClick = false;
    let files = document.getElementsByName("file");
    let a = 0;
    for (let i = 0; i < files.length; i++) {
        const file = files[i];
        let id = file.id;
        let el = file.getBoundingClientRect();
        let top = el.top //上边界
        let left = el.left;//左边界
        let right = el.right;//右边界
        let bottom = el.bottom;//下边界
        //原地点击
        if (this.start_x == this.end_x) {
            if (!(this.end_x >= left && this.end_x <= right && this.end_y > top && this.end_y < bottom)) {
                a += 1;
            }
        } else {
            //从左往右
            if (this.start_x < this.end_x) {
                //从下到上
                if (this.start_y > this.end_y) {
                    if (top < this.start_y && bottom > this.end_y) {
                        if(left<this.end_x&&right>this.start_x){
                            if (this.selectIdList.indexOf(id) === -1) {
                                this.selectIdList.push(id);
                                file.className = file.className + " ctrlClick";
                                file.style = 'border: 1px solid rgba(24, 135, 243, 0.5)'
                            }
                        }
                    }
                }
                //从上到下
                else{
                    if (top < this.end_y && bottom > this.start_y) {
                        if(left<this.end_x&&right>this.start_x){
                            if (this.selectIdList.indexOf(id) === -1) {
                                this.selectIdList.push(id);
                                file.className = file.className + " ctrlClick";
                                file.style = 'border: 1px solid rgba(24, 135, 243, 0.5)'
                            }
                        }
                    }
                }
            //从右往左
            }else{
                //从下到上
                if (this.start_y > this.end_y) {
                    if (top < this.start_y && bottom > this.end_y) {
                        if(left<this.start_x&&right>this.end_x){
                            if (this.selectIdList.indexOf(id) === -1) {
                                this.selectIdList.push(id);
                                file.className = file.className + " ctrlClick";
                                file.style = 'border: 1px solid rgba(24, 135, 243, 0.5)'
                            }
                        }
                    }
                }
                //从上到下
                else{
                    if (top < this.end_y && bottom > this.start_y) {
                        if(left<this.start_x&&right>this.end_x){
                            if (this.selectIdList.indexOf(id) === -1) {
                                this.selectIdList.push(id);
                                file.className = file.className + " ctrlClick";
                                file.style = 'border: 1px solid rgba(24, 135, 243, 0.5)'
                            }
                        }
                    }
                }

            }
        }
    }
    //如果点击空白处
    if (a == files.length) {
        this.selectIdList = [];
        this.setFileDivClass();
    }
},

核心思想就是判断目标是否在你移动的矩形区域内,比如从左往右中从下到上,判断每个目标矩形的上边距是否小于我的矩形区域的开始坐标的y坐标,下边距是否大于我的结束坐标的y坐标,左边距是否小于我的结束坐标的x坐标,右边距是否大于我的开始坐标的x坐标。
ps:与二维的线性规划有点相同

Logo

前往低代码交流专区

更多推荐