Jquery UI实现一次拖拽多个选中的元素操作


Posted in Javascript onDecember 01, 2020

项目需要,实现一个拖放操作,要求每次可以拖拽选中的多个元素,释放到目标容器后可排序。考虑了一下,觉得jquery-ui比较合适,毕竟它提供了项目需要的交互性事件机制。拖拽、释放、排序、选择等效果。而在实际的操作中,遇到个很多的问题,说明一下,最后附上效果图和代码。

1.本人使用的bootstrap框架,引入jquery-ui后,为元素添加拖拽方法后,提示该方法不是一个函数。查找原因,是bootstrap和jquery-uide的$ 标识符控制权冲突。在引入的jquery-ui的js前加上一下语句解决

<script>
  jQuery.noConflict();
</script>

2.jquery-ui的提供了选择操作(单选,多选),其中多选可以按住Ctrl配合鼠标单击多选,也可以鼠标在多个元素上拖拽进行多选。在为同一元素添加上选择操作和拖拽操作时,出现了问题。

a:多选的操作由于可以在元素上拖拽,与本身的拖拽事件有冲突(个人认为鼠标拖拽多选的效果并没有使用shift配合鼠标点击好用)。

b:jquery-ui没有发现可以将多个单独的元素同时拖拽。

不知道是本人愚钝没有发现jquery-ui可以使用本身自带的方法和属性,即可以支持多选又能拖拽选中的元素操作。哪位读者如果知晓还请告知。3Q!

总之,试验了多个jquery-ui的属性和事件,有去试着将jquery-ui的拖拽多选操作删除,也没有发现我需要的效果。所以,考虑了一下,决定不适用jquery-ui的选择操作。自己来写一个选择操作。与我们平常使用的事件触发机制一样。(鼠标单击单选,Ctrl+鼠标多选,Shift+鼠标多选),然后配合jquery-ui的drag和drop和sort事件机制实现拖拽排序效果。

再插一嘴,拖拽多个元素的效果,实际上是拖拽一个指定的dom元素,可以将需要拖拽的所有节点都放置到该元素中。这个需要配合jquery-ui的drag中的helper函数,返回一个新的拖拽元素集合。(关于jquery-ui的一些事件和属性大家可从网上查阅。不过说得也不尽详细,还需要自己去实验)。

Okay,贴出简单的效果图和代码

Jquery UI实现一次拖拽多个选中的元素操作

图一(拖放中效果)

Jquery UI实现一次拖拽多个选中的元素操作

图二(释放后效果)

效果图如上,左侧橙色为选中的节点,红色椭圆内部为鼠标拖拽的效果,3表示选中的元素呢个数;右侧的黄色区域表示可以释放和排序的容器。在该区域拖放时,节点会根据鼠标的位置自动排序,如图,如果释放鼠标后,左侧的3个节点就会移动到4.对应的黄色区域。

当然,以上的效果需要去重新给拖拽目标赋予新的元素,并且监听拖拽,释放等时间,编写用户自定义的逻辑。贴出自己的代码,一些事件和属性可以查阅jquery-ui的文档。

<!DOCTYPE html>
<html>
<head lang="en">
 <meta charset="UTF-8">
 <title></title>
 <link rel="stylesheet" href="assets/css/bootstrap.css" />
 <link rel="stylesheet" href="js/jquery-ui-1.12.1.dropable/jquery-ui.css" />
 <script src="js/jquery-1.11.2.js"></script>
 <script src="assets/js/bootstrap.js"/>
 <script>
  jQuery.noConflict();//解决jQuery控制权冲突问题
 </script>
 <script src="js/jquery-ui-1.12.1.dropable/jquery-ui.js"></script>
 <style>


  .selectable .ui-selecting{ background: #FECA40; }
  .selectable .ui-selected{ background: #F39814; color: white; }
  .selectable{ list-style-type: none; margin: 0; padding: 0; width: 80%; }
  .selectable li{
   list-style: none;
   margin: 3px; padding: 0.4em; font-size: 1.4em; height: 32px;moz-user-select: -moz-none;
   -moz-user-select: none;
   -o-user-select:none;
   -khtml-user-select:none;
   -webkit-user-select:none;
   -ms-user-select:none;
   user-select:none;
  }

  .drag_info_box{
   width:40px;
   height:40px;
   text-align: center;
   font-size:14px;
   line-height: 40px;
   background: #21aeff;
   color:#000000;
  }

 </style>
 <script>
  $(function(){





 //自定义多选方法
   var selected_begin_index,selected_end_index;
   $("#mydrag").on("mousedown",".selectable>li",function(e){

    var _selectable= $(this).parent();
    if(!e.ctrlKey && !e.shiftKey){ //没有按下Ctrl或Shift键
     if(!$(this).hasClass("ui-selected")){
      _selectable.children("li").removeClass("ui-selected");
     }
     $(this).addClass("ui-selected");
     selected_begin_index=_selectable.children("li").index(this);

    }else if(e.ctrlKey && !e.shiftKey){ //只按下Ctrl键
     $(this).addClass("ui-selected");
     selected_begin_index=_selectable.children("li").index(this);
    }else if((!e.ctrlKey && e.shiftKey) || (e.ctrlKey && e.shiftKey)){ //只按下Shift键或Ctrl和Shift键都按下
     _selectable.children("li").removeClass("ui-selected");
     $(this).addClass("ui-selected");

     if(selected_begin_index!=undefined){
      selected_end_index=_selectable.children("li").index(this);
     }else{
      selected_begin_index=_selectable.children("li").index(this);
     }

     if(selected_end_index>=selected_begin_index){
      for(var i=selected_begin_index;i<=selected_end_index;i++){
       _selectable.children("li").eq(i).addClass("ui-selected");
      }
     }else{
      for(var i=selected_end_index;i<=selected_begin_index;i++){
       _selectable.children("li").eq(i).addClass("ui-selected");
      }
     }

    }
   }).on("mouseup",".selectable>li",function(e){
    var _selectable= $(this).parent();
    if(!e.ctrlKey && !e.shiftKey){ //没有按下Ctrl或Shift键
     _selectable.children("li").removeClass("ui-selected");
     $(this).addClass("ui-selected");

    }
   });





//调用拖拽事件并重新规划处理方式
   $("#mydrag .selectable>li").draggable({
    revert: "invalid",
    containment: "document",
    cursor: "default",
    distance:10,
    zIndex:9,
    opacity:0.5,
    cursorAt: {
     left: 20,
     top:40
    },
    connectToSortable:"#mydrag .sample-group>ol",
    helper:function(event,ui){
     var drag_info_box=$("<div></div>").addClass("drag_info_box");
      drag_info_box.append($("<span></span>"));
      drag_info_box.append($('<input type="hidden" />'));
     return drag_info_box;
    },
    start: function( event, ui ) {
     var _drag_ele=ui.helper;
     _drag_ele.children("span").eq(0).text($("#mydrag .selectable>li.ui-selected").length);
     var selected_li_seq="";
     $("#mydrag .selectable>li.ui-selected").each(function(){
      selected_li_seq+= $("#mydrag .selectable>li").index(this)+",";
     });
     _drag_ele.children("input").eq(0).val(selected_li_seq.substr(0,selected_li_seq.length-1));
    },
    stop:function( event, ui ) {
     $(".selectable li").removeClass("ui-selected");
    }
   });


   $("#mydrag .sample-group>ol").droppable({
    activeClass: "ui-state-highlight",
    drop: function( event, ui ) {
     //这块如果是拖放到排序面板会执行两次,将该内容放到排序的stop方法中
    }
   });









//排序完毕后执行真正的释放操作
   $( "#mydrag .sample-group>ol" ).sortable({
    revert: true,
    stop: function( event, ui ) {

     if(ui.item.hasClass("drag_info_box")){
      var selected_li_arr=ui.item.children("input").eq(0).val().split(',');
      for(var i=0;i<selected_li_arr.length;i++){
       var _group_li_=$("<li></li>")
         .addClass("ui-state-highlight ui-sortable-handle").text($("#mydrag .selectable>li").eq(selected_li_arr[i]).text());
       //为该元素打上上传标签
       $("#mydrag .selectable>li").eq(selected_li_arr[i]).addClass("delete_flag")
       $( ".drag_info_box").before(_group_li_);
      }
     }
     $("#mydrag .selectable>li.delete_flag").remove();
     $(".drag_info_box").remove();
     $(this).sortable();
    }
   }).disableSelection();


  });
 </script>
</head>
<body>

 <div id="mydrag" style="width:1200px;height: auto;">
  <div class="col-sm-4" style="background: #eeeeee">
   <ol class="selectable">
    <li class="ui-widget-content">Item 1</li>
    <li class="ui-widget-content">Item 2</li>
    <li class="ui-widget-content">Item 3</li>
    <li class="ui-widget-content">Item 4</li>
    <li class="ui-widget-content">Item 5</li>
    <li class="ui-widget-content">Item 6</li>
    <li class="ui-widget-content">Item 7</li>
   </ol>
  </div>
  <div class="col-sm-4" style="background: greenyellow">
   <div class="sample-groups">
    <div class="sample-group" style="min-height: 80px;">
     <ol>
      <li class="ui-state-highlight">Item 1</li>
      <li class="ui-state-highlight">Item 2</li>
      <li class="ui-state-highlight">Item 3</li>
      <li class="ui-state-highlight">Item 4</li>
      <li class="ui-state-highlight">Item 5</li>
     </ol>
    </div>
   </div>
  </div>
  <div class="col-sm-4" style="background: green">
   <div class="row">
    <div style="background: #ffff00"></div>
    <div class="col-sm-5" style="background: blue"></div>
    <div class="col-sm-2" style="background: red"></div>
    <div class="col-sm-5" style="background: purple"></div>
   </div>
  </div>
 </div>

</body>
</html>

代码可用(没有写单选的释放效果,例子是目前的一个试验品,后续还要改成插件方式)。记录一下这两天的心得。主要是查找事件机制,整理思路和处理冲突问题花费了一定精力,得记上一笔。

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

Javascript 相关文章推荐
JavaScript While 循环基础教程
Apr 05 Javascript
Js 中debug方式
Feb 07 Javascript
各情景下元素宽高的获取实现代码
Sep 13 Javascript
js调试工具console.log()方法查看js代码的执行情况
Aug 08 Javascript
JQuery工具函数汇总
Jun 15 Javascript
easyui Droppable组件实现放置特效
Aug 19 Javascript
jquery遍历json对象集合详解
May 18 Javascript
微信小程序模版渲染详解
Jan 26 Javascript
vue和react等项目中更简单的实现展开收起更多等效果示例
Feb 22 Javascript
vue集成百度UEditor富文本编辑器使用教程
Sep 21 Javascript
Javascript如何实现扩充基本类型
Aug 26 Javascript
jQuery-App输入框实现实时搜索
Nov 19 jQuery
浅谈js继承的实现及公有、私有、静态方法的书写
Oct 28 #Javascript
jQuery.datatables.js插件用法及api实例详解
Oct 28 #Javascript
扩展jquery easyui tree的搜索树节点方法(推荐)
Oct 28 #Javascript
浅谈jQuery中的eq()与DOM中element.[]的区别
Oct 28 #Javascript
js基础之DOM中document对象的常用属性方法详解
Oct 28 #Javascript
Javascript+CSS3实现进度条效果
Oct 28 #Javascript
js基础之DOM中元素对象的属性方法详解
Oct 28 #Javascript
You might like
PHP strtotime函数详解
2009/12/18 PHP
基于php缓存的详解
2013/05/15 PHP
PHP快速生成各种信息提示框的方法
2016/02/03 PHP
PHP实现的mysql操作类【MySQL与MySQLi方式】
2017/10/07 PHP
PHP等比例压缩图片的实例代码
2018/07/26 PHP
js程序中美元符号$是什么
2008/06/05 Javascript
js文字滚动停顿效果代码
2008/06/28 Javascript
jquery 常用操作整理 基础入门篇
2009/10/14 Javascript
使用js操作css实现js改变背景图片示例
2014/03/10 Javascript
extjs 如何给column 加上提示
2014/07/29 Javascript
基于 Docker 开发 NodeJS 应用
2014/07/30 NodeJs
了不起的node.js读书笔记之mongodb数据库交互
2014/12/22 Javascript
js实现拖拽效果(构造函数)
2015/12/14 Javascript
js图片切换具体实现代码
2016/10/13 Javascript
jquery对象和DOM对象的相互转换详解
2016/10/18 Javascript
深入了解JavaScript的逻辑运算符(与、或)
2016/12/20 Javascript
浅谈javascript中的数据类型转换
2016/12/27 Javascript
js 动态生成html 触发事件传参字符转义的实例
2017/02/14 Javascript
js实现窗口全屏示例详解
2019/09/17 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
JavaScript 实现下雪特效的示例代码
2020/09/09 Javascript
用python + hadoop streaming 分布式编程(一) -- 原理介绍,样例程序与本地调试
2014/07/14 Python
Python转换HTML到Text纯文本的方法
2015/01/15 Python
在IIS服务器上以CGI方式运行Python脚本的教程
2015/04/25 Python
Python MySQL数据库连接池组件pymysqlpool详解
2017/07/07 Python
使用Python爬了4400条淘宝商品数据,竟发现了这些“潜规则”
2018/03/23 Python
Python Django给admin添加Action的方法实例详解
2019/04/29 Python
python实现布隆过滤器及原理解析
2019/12/08 Python
TensorFlow内存管理bfc算法实例
2020/02/03 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
2020/04/09 Python
Python中bisect的用法及示例详解
2020/07/20 Python
经典优秀个人求职自荐信格式
2013/09/25 职场文书
五年级数学教学反思
2014/02/11 职场文书
“六查”、“三学”、“三干”查摆问题整改措施
2014/09/27 职场文书
乔迁之喜答谢词
2015/01/05 职场文书
公司周年庆典致辞
2015/07/30 职场文书