js实现鼠标拖拽多选功能示例


Posted in Javascript onAugust 01, 2017

最近做了一个用js实现鼠标拖拽多选的功能,于是整理了一下思路,写了一个小demo:

遮罩出现:

js实现鼠标拖拽多选功能示例

被遮罩盖住的,即为选中的块(背景色为粉色)

js实现鼠标拖拽多选功能示例

下面是具体代码,注释已在文中,与大家交流。

<!DOCTYPE html>
<html>
<head>
  <title>鼠标拖拽多选功能</title>
  <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
  <style type="text/css">
    *{
      box-sizing:border-box;
    }
    ul{
      width:500px;
      height:auto;
      margin:0;
      padding:20px;
      font-size: 0;
      /*需设置定位*/
      position:relative;
    }
    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;
    }
    .selected{
      background-color: pink;
    }
  </style>
</head>
<body>
  <ul class="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
    <li>11</li>
    <li>12</li>
    <li>13</li>
    <li>14</li>
    <li>15</li>
    <li>16</li>
    <li>17</li>
    <li>18</li>
    <li>19</li>
    <li>20</li>
    <li>21</li>
    <li>22</li>
    <!-- 鼠标拖拽出的遮罩 (定位为 position:absolute)-->
    <!-- 遮罩最好是在绑定了mouseover事件的元素内部,并且不要阻止遮罩的冒泡事件。这样鼠标移到了遮罩上面,依然可以利用冒泡执行父元素的mouseover事件,就不会出现遮罩只能扩大,不能缩小的情况了(亲自试过) -->
    <div id="moveSelected"></div>
  </ul>
</body>
</html>
<script type="text/javascript">
  $(document).ready(function(){
    let moveSelected=$('#moveSelected')[0];
    let flag=false;//是搜开启拖拽的标志
    let oldLeft=0;//鼠标按下时的left,top
    let oldTop=0;
    let selectedList=[];//拖拽多选选中的块集合

    // 鼠标按下时开启拖拽多选,将遮罩定位并展现
    $(".list").mousedown(function(event) {
      flag=true;
      moveSelected.style.top=event.pageY+'px';
      moveSelected.style.left=event.pageX+'px';
      oldLeft=event.pageX;
      oldTop=event.pageY;
      event.preventDefault(); // 阻止默认行为
      event.stopPropagation(); // 阻止事件冒泡
    });
    // 鼠标移动时计算遮罩的位置,宽 高
    $(".list").mousemove(function(event) {
      if(!flag) return;//只有开启了拖拽,才进行mouseover操作
      if(event.pageX<oldLeft){//向左拖
        moveSelected.style.left=event.pageX+'px';
        moveSelected.style.width=(oldLeft-event.pageX)+'px';
      }else{
        moveSelected.style.width=(event.pageX-oldLeft)+'px';
      }
      if(event.pageY<oldTop){//向上
        moveSelected.style.top=event.pageY+'px';
        moveSelected.style.height=(oldTop-event.pageY)+'px';
      }else{
        moveSelected.style.height=(event.pageY-oldTop)+'px';
      }
      event.preventDefault(); // 阻止默认行为
      event.stopPropagation(); // 阻止事件冒泡
    });
    //鼠标抬起时计算遮罩的right 和 bottom,找出遮罩覆盖的块,关闭拖拽选中开关,清除遮罩数据
    $(".list").mouseup(function(event) {
      moveSelected.style.bottom=Number(moveSelected.style.top.split('px')[0])+Number(moveSelected.style.height.split('px')[0]) + 'px';
      moveSelected.style.right=Number(moveSelected.style.left.split('px')[0])+Number(moveSelected.style.width.split('px')[0])+'px';
      findSelected();
      flag=false;
      clearDragData();
      event.preventDefault(); // 阻止默认行为
      event.stopPropagation(); // 阻止事件冒泡
    });
    $(".list").mouseleave(function(event) {
      flag=false;
      moveSelected.style.width=0;
      moveSelected.style.height=0;
      moveSelected.style.top=0;
      moveSelected.style.left=0;
      event.preventDefault(); // 阻止默认行为
      event.stopPropagation(); // 阻止事件冒泡
    });
    function findSelected(){
      let blockList=$('.list').find('li');
      for(let i=0;i<blockList.length;i++){
        //计算每个块的定位信息
        let left=$(blockList[i]).offset().left;
        let right=$(blockList[i]).width()+left;
        let top=$(blockList[i]).offset().top;
        let bottom=$(blockList[i]).height()+top;
        //判断每个块是否被遮罩盖住(即选中)
        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];
        if((leftFlag || rightFlag) && (topFlag || bottomFlag)){
          selectedList.push(blockList[i]);
          $(blockList[i]).addClass('selected');
        }
      }
      console.log(selectedList);
    }
    function clearDragData(){
      moveSelected.style.width=0;
      moveSelected.style.height=0;
      moveSelected.style.top=0;
      moveSelected.style.left=0;
      moveSelected.style.bottom=0;
      moveSelected.style.right=0;
    }
  });
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
Feb 18 Javascript
基于jquery实现拆分姓名的方法(纯JS版)
May 08 Javascript
Javascript核心读书有感之类型、值和变量
Feb 11 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
Sep 15 Javascript
从重置input file标签中看jQuery的 .val() 和 .attr(“value”) 区别
Jun 12 Javascript
JS正则替换去空格的方法
Mar 24 Javascript
js实现京东轮播图效果
Jun 30 Javascript
全选复选框JavaScript编写小结(附代码)
Aug 16 Javascript
JS 中document.write()的用法和清空的原因浅析
Dec 04 Javascript
如何将你的AngularJS1.x应用迁移至React的方法
Feb 01 Javascript
javascrpt密码强度校验函数详解
Mar 18 Javascript
Element Cascader 级联选择器的使用示例
Jul 27 Javascript
使用Node.js实现RESTful API的示例
Aug 01 #Javascript
关于jquery form表单序列化的注意事项详解
Aug 01 #jQuery
js下拉菜单生成器dropMenu使用方法详解
Aug 01 #Javascript
简述jQuery Easyui一些用法
Aug 01 #jQuery
js图片上传的封装代码
Aug 01 #Javascript
使用重写url机制实现验证码换一张功能
Aug 01 #Javascript
js实现拖拽上传图片功能
Aug 01 #Javascript
You might like
PHP日期时间函数的高级应用技巧
2009/05/16 PHP
PHP判断指定时间段的2个方法
2014/03/14 PHP
PHP实现Javascript中的escape及unescape函数代码分享
2015/02/10 PHP
CodeIgniter常用知识点小结
2016/05/26 PHP
Yii2表单事件之Ajax提交实现方法
2017/05/04 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
自制轻量级仿jQuery.boxy对话框插件代码
2010/10/26 Javascript
Javascript Object 对象学习笔记
2014/12/17 Javascript
node.js中的fs.readlink方法使用说明
2014/12/17 Javascript
Javascript 实现全屏滚动实例代码
2016/12/31 Javascript
Nodejs+Socket.io实现通讯实例代码
2017/02/13 NodeJs
AngularJS中controller控制器继承的使用方法
2017/11/03 Javascript
Node.js使用cookie保持登录的方法
2018/05/11 Javascript
使用FormData实现上传多个文件
2018/12/04 Javascript
微信小程序使用map组件实现获取定位城市天气或者指定城市天气数据功能
2019/01/22 Javascript
vue+webpack 更换主题N种方案优劣分析
2019/10/28 Javascript
VUE 实现element upload上传图片到阿里云
2020/08/12 Javascript
python判断列表的连续数字范围并分块的方法
2018/11/16 Python
详解如何设置Python环境变量?
2019/05/13 Python
使用Python中的reduce()函数求积的实例
2019/06/28 Python
Python利用requests模块下载图片实例代码
2019/08/12 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
2019/10/30 Python
python飞机大战pygame碰撞检测实现方法分析
2019/12/17 Python
在 Python 中接管键盘中断信号的实现方法
2020/02/04 Python
python+selenium+chromedriver实现爬虫示例代码
2020/04/10 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
python 读txt文件,按‘,’分割每行数据操作
2020/07/05 Python
Selenium之模拟登录铁路12306的示例代码
2020/07/31 Python
千禧酒店及度假村官方网站:Millennium Hotels and Resorts
2019/05/10 全球购物
JBL加拿大官方商店:扬声器、耳机等
2020/10/23 全球购物
初任培训自我鉴定
2013/10/07 职场文书
历史教育专业个人求职信
2013/12/13 职场文书
毕业生求职自荐书范文
2014/03/27 职场文书
家长对孩子的评语
2014/04/18 职场文书
小学教师个人先进事迹材料
2014/05/17 职场文书
初中生庆国庆演讲稿范文2014
2014/09/25 职场文书