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 相关文章推荐
jQuery 翻牌或百叶窗效果(内容三秒自动切换)
Jun 14 Javascript
js 输出内容到新窗口具体实现代码
May 31 Javascript
javascript 实现键盘上下左右功能的小例子
Sep 15 Javascript
jQuery弹出层插件Lightbox_me使用指南
Apr 21 Javascript
JS实现生成会变大变小的圆环实例
Aug 05 Javascript
jquery常用函数与方法汇总
Sep 01 Javascript
js实现的奥运倒计时时钟效果代码
Dec 09 Javascript
Vue的elementUI实现自定义主题方法
Feb 23 Javascript
微信小程序系列之自定义顶部导航功能
May 21 Javascript
vue v-for 使用问题整理小结
Aug 04 Javascript
layui table 表格上添加日期控件的两种方法
Sep 28 Javascript
vue实现设置载入动画和初始化页面动画效果
Oct 28 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
重置版战役片段
2020/04/09 魔兽争霸
如何对PHP程序中的常见漏洞进行攻击(上)
2006/10/09 PHP
PHP 作用域解析运算符(::)
2010/07/27 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
php出租房数据管理及搜索页面
2017/05/23 PHP
Javascript客户端脚本的设计和应用
2006/08/21 Javascript
form表单只提交数据而不进行页面跳转的解决方案
2013/09/18 Javascript
使用focus方法让光标默认停留在INPUT框
2014/07/29 Javascript
Node.js中使用Buffer编码、解码二进制数据详解
2014/08/16 Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
2020/06/19 Javascript
jquery ui 实现 tab标签功能示例【测试可用】
2019/07/25 jQuery
对layer弹出框中icon数字参数的说明介绍
2019/09/04 Javascript
通过layer实现可输入的模态框的例子
2019/09/27 Javascript
[03:57]《不朽》——2015DOTA2国际邀请赛—中国军团出征主题曲MV
2015/07/15 DOTA
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
Python 错误和异常小结
2013/10/09 Python
python编写暴力破解FTP密码小工具
2014/11/19 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
2018/05/26 Python
Python检测数据类型的方法总结
2019/05/20 Python
python pyinstaller 加载ui路径方法
2019/06/10 Python
pandas的qcut()方法详解
2019/07/06 Python
Python使用文件操作实现一个XX信息管理系统的示例
2020/07/02 Python
python处理写入数据代码讲解
2020/10/22 Python
CSS3实现头像旋转效果
2017/03/13 HTML / CSS
HTML5引入的新数组TypedArray介绍
2012/12/24 HTML / CSS
中学教师实习自我鉴定
2013/09/28 职场文书
音乐器材管理制度
2014/01/31 职场文书
会计专业求职信范文
2014/03/16 职场文书
《回乡偶书》教学反思
2014/04/12 职场文书
大学生个人求职信
2014/06/02 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
写给老师的感谢信
2015/01/20 职场文书
消防演习感想
2015/08/10 职场文书
Nginx域名转发https访问的实现
2021/03/31 Servers
sentinel支持的redis高可用集群配置详解
2022/04/01 Redis
hive数据仓库新增字段方法
2022/06/25 数据库