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 相关文章推荐
ExtJS4 组件化编程,动态加载,面向对象,Direct
May 12 Javascript
jQuery插件jquery-barcode实现条码打印的方法
Nov 25 Javascript
给easyui datebox扩展一个清空的实例
Nov 09 Javascript
BootStrap 弹出层代码
Feb 09 Javascript
jQuery中layer分页器的使用
Mar 13 Javascript
微信小程序page的生命周期和音频播放及监听实例详解
Apr 07 Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
Feb 09 Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 Javascript
基于layPage插件实现两种分页方式浅析
Jul 27 Javascript
关于layui导航栏不展示下拉列表的解决方法
Sep 25 Javascript
VUEX 数据持久化,刷新后重新获取的例子
Nov 12 Javascript
vue实现移动端返回顶部
Oct 12 Javascript
浅谈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连接access数据库
2015/03/27 PHP
cssQuery()的下载与使用方法
2007/01/12 Javascript
JS 两个字符串时间的天数差计算
2013/08/25 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
jquery实现html页面 div 假分页有原理有代码
2014/09/06 Javascript
jquery trigger实现联动的方法
2016/02/29 Javascript
jQuery常用的一些技巧汇总
2016/03/26 Javascript
JavaScript跨域调用基于JSON的RESTful API
2016/07/09 Javascript
slideToggle+slideup实现手机端折叠菜单效果
2017/05/25 Javascript
关于在vue-cli中使用微信自动登录和分享的实例
2017/06/22 Javascript
React Native中TabBarIOS的简单使用方法示例
2017/10/13 Javascript
微信小程序实现下载进度条的方法
2017/12/08 Javascript
实例讲解Vue.js中router传参
2018/04/22 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
Vue2实时监听表单变化的示例讲解
2018/08/30 Javascript
angularjs1.5 组件内用函数向外传值的实例
2018/09/30 Javascript
基于JS实现web端录音与播放功能
2019/04/17 Javascript
vue实现简单的日历效果
2020/09/24 Javascript
pm2启动ssr失败的解决方法
2019/06/29 Javascript
VUE+elementui组件在table-cell单元格中绘制微型echarts图
2020/04/20 Javascript
vue-quill-editor插入图片路径太长问题解决方法
2021/01/08 Vue.js
wxPython实现窗口用图片做背景
2018/04/25 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
Python pandas实现excel工作表合并功能详解
2019/08/29 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
波兰在线体育用品商店:Hop-Sport.pl
2019/07/23 全球购物
ellesse美国官方商店:意大利高级运动服品牌
2019/10/29 全球购物
SEPHORA丝芙兰德国官方购物网站:化妆品、护肤品和香水
2020/01/21 全球购物
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
应聘教师推荐信
2013/10/31 职场文书
《池塘边的叫声》教学反思
2014/04/12 职场文书
先进典型事迹材料
2014/12/29 职场文书
个人求职自荐信范文
2015/03/06 职场文书
离婚起诉状范本
2015/05/19 职场文书
房产遗嘱范本
2015/08/06 职场文书
CSS 制作波浪效果的思路
2021/05/18 HTML / CSS