js鼠标拖拽多选

<!DOCTYPE html>
<html>

<head>
  <title>鼠标拖拽多选功能</title>
  <script src="./jquery.js"></script>
  <style type="text/css">
    * {
      box-sizing: border-box;
    }

    ul {
      width: 500px;
      height: auto;
      /* margin: 0; */
      margin-left: 200px;
      margin-top: 100px;
      padding: 20px;
      font-size: 0;
      /*需设置定位*/
      position: relative;
      border: 1px solid red;
    }

    li {
      width: 70px;
      height: 70px;
      margin: 10px;
      padding: 0;
      display: inline-block;
      vertical-align: top;
      font-size: 13px;
      border: 1px solid #d9d9d9;
    }

    #moveSelected {
      position: absolute;
      background-color: blue;
      opacity: 0.3;
      border: 1px dashed #d9d9d9;
      top: 0;
      left: 0;
      /* border: 1px solid blue; */
    }

    .selected {
      background-color: pink;
    }

    .box {
      width: 500px;
      height: 500px;
      background-color: skyblue;
    }

  </style>
</head>

<body>


  <ul class="list">
    <li draggable="true">1</li>
    <li draggable="true">2</li>
    <li draggable="true">3</li>
    <li draggable="true">4</li>
    <li draggable="true">5</li>
    <li draggable="true">6</li>
    <li draggable="true">7</li>
    <li draggable="true">8</li>
    <li draggable="true">9</li>
    <li draggable="true">10</li>
    <!-- 鼠标拖拽出的遮罩 (定位为  position:absolute)-->
    <!-- 遮罩最好是在绑定了mouseover事件的元素内部,并且不要阻止遮罩的冒泡事件。这样鼠标移到了遮罩上面,依然可以利用冒泡执行父元素的mouseover事件,就不会出现遮罩只能扩大,不能缩小的情况了(亲自试过) -->
    <div id="moveSelected"></div>
  </ul>
  <script type="text/javascript">
    let flag = false; //是搜开启拖拽的标志
    let oldLeft = 0;  //鼠标按下时的left
    let oldTop = 0;   //鼠标按下时的top
    let outLeft = 0;  //外层元素left,ul margin-left
    let outTop = 0;   //外层元素top, ul margin-top
    let selectedList = []; //拖拽多选选中的块集合
    let moveSelected = document.getElementById('moveSelected'); // 选中阴影


    //相当于$(document).ready(function(){})
    $(function () {

      //获取外层元素left,top坐标
      getOutLeftTop()

      /**
       * 鼠标按下时开启拖拽多选,将遮罩定位并展现
       */
      $(".list").mousedown(function (event) {
        console.log("鼠标按下");
        //清空选中数据
        clearSelectData()

        //拖拽状态
        flag = true;
        //拖拽开始位置数据,left-外层元素left,top-外层元素top
        // moveSelected.style.top = event.pageY + 'px';
        // moveSelected.style.left = event.pageX + 'px';
        moveSelected.style.top = (event.pageY-outTop)<0 ? 0 : (event.pageY-outTop) + 'px';
        moveSelected.style.left = (event.pageX-outLeft)<0 ? 0 : (event.pageX-outLeft)  + 'px';
        oldLeft = event.pageX;
        oldTop = event.pageY;
        console.log("鼠标按下",oldLeft,oldTop);
        //清除默认行为,冒泡事件
        clearEvent(event)
      });
      

      /**
       * 鼠标移动时计算遮罩的位置,宽 高
       */
      $(".list").mousemove(function (event) {
        // console.log("鼠标移动");
        if (!flag) return; //只有开启了拖拽,才进行mouseover操作
        //left-外层元素left,top-外层元素top
        let ex = event.pageX - outLeft //鼠标x
        let ey = event.pageY - outTop  //鼠标y
        let ox = oldLeft - outLeft     //遮罩层x
        let oy = oldTop - outTop       //遮罩层y
        // console.log("鼠标移动",ex,ey,ox,oy);
        //向左 
        if (event.pageX < oldLeft) { 
          moveSelected.style.left = ex + 'px';
          moveSelected.style.width = (ox - ex) + 'px';
        } else {//向右
          moveSelected.style.width = (ex - ox) + 'px';
        }
        //向上
        if (event.pageY < oldTop) { 
          moveSelected.style.top = ey + 'px';
          moveSelected.style.height = (oy - ey) + 'px';
        } else {//向下
          moveSelected.style.height = (ey - oy) + 'px';
        }

        //清除默认行为,冒泡事件
        clearEvent(event)
      });


      /**
       * 鼠标抬起,获取选中元素,清除遮罩数据
       */
      $(".list").mouseup(function (event) {
        console.log("鼠标抬起");
        //遮罩层bottom
        moveSelected.style.bottom = Number(moveSelected.style.top.split('px')[0]) + Number(moveSelected.style
          .height.split('px')[0]) + 'px';
        //遮罩层right
        moveSelected.style.right = Number(moveSelected.style.left.split('px')[0]) + Number(moveSelected.style
          .width.split('px')[0]) + 'px';
        //获取遮罩覆盖的元素
        if(flag) findSelected();
        //清除遮罩数据
        clearDragData();

        //清除默认行为,冒泡事件
        clearEvent(event)
      });


      /**
       * 鼠标移除,清除遮罩数据
       */
      $(".list").mouseleave(function (event) {
        console.log("鼠标移除");
        //遮罩层属性清空
        clearDragData();

        //清除默认行为,冒泡事件
        clearEvent(event)
      });


      /**
       * 获取遮罩覆盖的元素
       */
      function findSelected() {
        //待选中的元素
        let blockList = $('.list').find('li');
        //计算每个元素是否被覆盖选中,添加选中样式
        for (let i = 0; i < blockList.length; i++) {

          //1.计算每个元素的定位信息,left-外层元素left,top-外层元素top
          let left = $(blockList[i]).offset().left - outLeft;
          let right = $(blockList[i]).width() + left;
          let top = $(blockList[i]).offset().top - outTop;
          let bottom = $(blockList[i]).height() + top;
          
          // console.log("鼠标移动1",left,right,top,bottom);

          //2.判断每个元素是否被遮罩盖住(即选中)
          let leftFlag = moveSelected.style.left.split('px')[0] <= left && left <= moveSelected.style.right.split(
            'px')[0];
          let rightFlag = moveSelected.style.left.split('px')[0] <= right && right <= moveSelected.style.right
            .split(
              'px')[0];
          let topFlag = moveSelected.style.top.split('px')[0] <= top && top <= moveSelected.style.bottom.split(
            'px')[
            0];
          let bottomFlag = moveSelected.style.top.split('px')[0] <= bottom && bottom <= moveSelected.style.bottom
            .split('px')[0];


          //3.左或右任意一边被覆盖,上或下任意一边被覆盖,就算被选中
          if ((leftFlag || rightFlag) && (topFlag || bottomFlag)) {
            //选中数组不存在,推送到选中数组,去重
            // selectedList.push(blockList[i]);
            if(selectedList.indexOf($(blockList[i]).text())<0){
              selectedList.push($(blockList[i]).text());
            }
            //选中元素他添加选中样式
            $(blockList[i]).addClass('selected');
          }
        }
        console.log("选中的元素",selectedList);
        console.log("选中状态",flag);
      }




      /**
       * 鼠标左键点击选中元素以外区域清空已经选择的数据
       */
      $(document).mouseup(function (e) {
        //选中元素区域
        let con = $('.list')
        if (!con.is(e.target) && con.has(e.target).length === 0) {
          console.log('鼠标点击选中元素区域外,清空选中数据')
          //清空选中数据
          clearSelectData()
        }
      })

      /**
       * 元素单选
       */
      $('.list').find('li').click(function (event) {
        console.log('元素单选')
        //清空选中数据
        clearSelectData()
      
        //添加选中状态
        $(this).addClass('selected');
        if(selectedList.indexOf($(this).text())<0){
          selectedList.push($(this).text());
        }
        console.log("选中的元素",selectedList);
        console.log("选中状态",flag);
        
        //清除默认行为,冒泡事件
        clearEvent(event)
      })
    });

    /**
     * 清除遮罩数据
     */
    function clearDragData() {
      //清空选中状态
      flag = false;
      //清空遮罩层数据
      moveSelected.style.width = 0;
      moveSelected.style.height = 0;
      moveSelected.style.top = 0;
      moveSelected.style.left = 0;
      moveSelected.style.bottom = 0;
      moveSelected.style.right = 0;
    }

    /**
     * 清空选中数据,选中状态
     */
    function clearSelectData(){
      //清空选中状态
      flag = false
      //清空选中数据
      selectedList = []
      //清空选中样式
      $('.list').find('li').removeClass('selected');
    }

    /**
     * 清除默认行为,冒泡事件
     */
    function clearEvent(event) {
      event.preventDefault(); // 阻止默认行为
      event.stopPropagation(); // 阻止事件冒泡
    }

    /**
     * 获取元素顶部x轴
     */
    function getElementLeft(element){
        let actualLeft = element.offsetLeft;
        let current = element.offsetParent;
        while (current !== null){       
            actualLeft += current.offsetLeft;
            current = current.offsetParent;
        }
        return actualLeft;
    }
   
    /**
     * 获取元素顶部y轴
     */
    function getElementTop(element){
        let actualTop = element.offsetTop;
        let current = element.offsetParent;
        while (current !== null){       
            actualTop += current. offsetTop;
            current = current.offsetParent;
        }
        return actualTop;
    }

    /**
     * 获取外层元素left,top值
     */
    function getOutLeftTop(){
      let listE = document.getElementsByClassName('list')[0]
      outLeft = getElementLeft(listE)
      outTop = getElementTop(listE)
      console.log('外层元素左上角坐标',outLeft,outTop)
    }

  </script>
</body>

</html>

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值