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

项目需要,实现一个拖放操作,要求每次可以拖拽选中的多个元素,释放到目标容器后可排序。考虑了一下,觉得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,贴出简单的效果图和代码

                         图一(拖放中效果)

                         图二(释放后效果)

效果图如上,左侧橙色为选中的节点,红色椭圆内部为鼠标拖拽的效果,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>

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

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

(0)

相关推荐

  • 浅谈jquery之on()绑定事件和off()解除绑定事件

    off()函数用于移除元素上绑定的一个或多个事件的事件处理函数. off()函数主要用于解除由on()函数绑定的事件处理函数. 该函数属于jQuery对象(实例). 语法 jQuery 1.7 新增该函数.其主要有以下两种形式的用法: 用法一: jQueryObject.off( [ events [, selector ] [, handler ] ] ) 用法二: jQueryObject.off( eventsMap [, selector ] ) 参数 参数 描述 events 可选/S

  • jQuery.datatables.js插件用法及api实例详解

    1.DataTables的默认配置 $(document).ready(function() { $('#example').dataTable(); } ); 示例:http://www.guoxk.com/html/DataTables/Zero-configuration.html 2.DataTables的一些基础属性配置 "bPaginate": true, //翻页功能 "bLengthChange": true, //改变每页显示数据数量 "

  • jquery数组过滤筛选方法grep()简介

    jquery中有个grep()方法用于数组元素过滤筛选,悲剧的是,平时我们用的api文档中找不到这个说明.查看官方说明:http://api.jquery.com/jQuery.grep/ grep()的使用方法: grep(array,callback,invert) array:待过滤数组; callback:处理数组中的每个元素,并过滤元素,该函数中包含两个参数,第一个是当前数组元素的值,一个是当前数组元素的下标,即元素索引值.此函数应返回一个布尔值.另外,此函数可设置为一个字符串,当设置

  • 基于Layer+jQuery的自定义弹框

    目的:XXXX项目中,很多的弹窗是利用freemarker的网页标签追加的形式实现的,网页弹框只是将隐藏的div显示出来,这样会使网页在预加载时速度变慢,增加页面加载和响应时间 解决方法如下:<已分中心管理的添加分中心弹框实现机制为例> 1.弹框页面部分的html代码和css抽离 html : html/configure/layer-win/_group-add-layer.html css : css/common/componnentWin.css <自定义弹窗通用样式> 子

  • jquery移除了live()、die(),新版事件绑定on()、off()的方法

    我蛋疼了快10分钟,怎么调用都是报错,最后一查,原来jquery已经移除了live()和die()方法.使用了新的事件绑定方法on().解除绑定方法off(). 新的绑定方法on()和比live()相比,效率比之前的高.因为live()是固定在document节点上的.如果绑定的元素嵌套在很深的层中,那么事件一级级的传递必将影响到效率.而on()是绑定在$()选择的元素上,嵌套深度可自由选择. on()的参数 on( events [, selector ] [, data ], handler

  • jQuery grep()方法详解及实例代码

    什么是jQuery.grep()? jQuery.grep()是一个查找满足过滤函数的数组元素的函数.原始数组不受影响,返回值为数组. 用法介绍: 写法: jQuery.grep( array, function(elementOfArray, indexInArray) [, invert ] ) 参数介绍: array 类型: Array 用于查询元素的数组. function(elementOfArray, indexInArray) 类型: Function() 该函数来处理每项元素的比

  • 浅析jquery数组删除指定元素的方法:grep()

    遇到的问题 今天遇到一个问题,删除数组中的一个指定元素,并返回新的数组. 我定义的js数组是这样的: var sexList=new Array[3]; sexList[0]="1"; sexList[1]="2"; sexList[2]=""; 想达到的效果 我想达到的效果是这样的: 删除索引=1的元素,并返回新数组. 返回的结果是: var sexList=new Array("1",""); 我们知道

  • 关于Jquery中的bind(),on()绑定事件方式总结

    一.bind() 使用方式:$(selector).bind(event,data,function) event:必需项:添加到元素的一个或多个事件,例如 click,dblclick等: 单事件处理:例如 $(selector).bind("click",data,function); 多事件处理:1.利用空格分隔多事件,例如 $(selector).bind("click dbclick mouseout",data,function); 2.利用大括号灵活定

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

    项目需要,实现一个拖放操作,要求每次可以拖拽选中的多个元素,释放到目标容器后可排序.考虑了一下,觉得jquery-ui比较合适,毕竟它提供了项目需要的交互性事件机制.拖拽.释放.排序.选择等效果.而在实际的操作中,遇到个很多的问题,说明一下,最后附上效果图和代码. 1.本人使用的bootstrap框架,引入jquery-ui后,为元素添加拖拽方法后,提示该方法不是一个函数.查找原因,是bootstrap和jquery-uide的$ 标识符控制权冲突.在引入的jquery-ui的js前加上一下语句

  • jquery插件jquery.beforeafter.js实现左右拖拽分隔条对比图片的方法

    本文实例讲述了jquery插件jquery.beforeafter.js实现左右拖拽分隔条对比图片的方法.分享给大家供大家参考.具体如下: 左右拖拽切换对比图片效果,运行效果后,图片中间有个拖动条,拖动左右滑动,可看到图片不一样的效果,女模特的脸变嫩了,呵呵,其实是用了两张背景图片实现的,这就需要jquery.beforeafter.js插件了,拖动时候的小图标不见了,路径可以在jquery.beforeafter.js中设置,不多说了. 运行效果截图如下: 在线演示地址如下: http://d

  • jQuery表格列宽可拖拽改变且兼容firfox

    本demo使用jQuery包,实现表格列宽可拖拽功能,并实现页面reset时的重新布局.使用jQuery,方便函数的调用,给要处理的表格添加id 后,直接调用$("#id").movedTh()即可方便实现,修改了firfox的兼容性. 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

  • 如何使用jQuery Draggable和Droppable实现拖拽功能

    在以前的文章中我已经介绍了web开发中基本拖放原理,现在给出需要完成的功能.最后运行的效果如下图所示: 主要功能需求说明:1.左侧的元素结构最后会通过Ajax call服务器的数据来生成,能支持多级元素.父节点可以折叠起来 2.用户可以通过拖放的操作,将元素从左侧拖放到右侧.如果是拖的父节点元素,那么需要把它子节点的元素一并拖到右边 3.元素放到右侧,右侧可以接受元素的区域有2种可能.一种新建一个区域,就类似"华东交通大学"所示.另外一种就是拖放到已经有元素的区域.两者的关系是&quo

  • jQuery实现表格的数据拖拽

    jQuery实现将一个ant-table的数据拖拽复制到另一个ant-table,供大家参考,具体内容如下 需求 1.ant-design-vue2.将一个嵌套在drawer中的table数据拖拽复制到drawer外面的table中 效果 拖拽中 拖拽后 HTML <el-button type="text" size="small" class="text-btn" @click="choseField">选择字

  • jquery实现移动端悬浮拖拽框

    使用jquery 实现了一个基础的悬浮弹拖拽窗, 根据自己的需求去完善动效. 分享给大家供大家参考,具体如下: 演示效果 代码块 需要引入jquery , 引入本地或线上根据自己的情况修改 <!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <meta http-equiv="X-UA-Compatible" c

  • javascript实现拖拽并替换网页块元素

    找了一些现成的插件,发现都不太符合我的需求,于是参考网上的例子自己实现了一个,还没有优化.  还是贴代码吧: dragtoreplace DragToReplaceDeom #displayRoom{background:#eee;position:relative;float:left;clear:both;padding:30px 0px 0px 20px;margin-left:20px;margin-top:10px;} .row{display:inline-block;float:l

  • 通过JQuery,JQueryUI和Jsplumb实现拖拽模块

    前言 由于时间的原因.这个demo只兼容IE8,IE9.其他浏览器暂时不支持.不过jsplumb本身是支持各种浏览器的. 写这篇文章是因为我在实际开发中遇到一个需求,支持拖拽模块到指定的容器里.并且每个模块会有自己的output 和input.开始觉得很酷也很变态.经过一段时间的调研,特把结果分享给大家.不足之处,敬请指正. 看了题目里的3个J.可能有的朋友觉得头晕,需要这么多东东?我先逐一介绍一下. 第一个jquery是我们平时经常使用的jquery 库.它可以让你用很少的代码实现一些很酷的j

  • JQuery Dialog(JS 模态窗口,可拖拽的DIV)

    效果图 调用示意图 交互示意图 如上图所示,这基本是JQueryDialog的完整逻辑流程了. 1.用户点击模态窗口的"提交"按钮时,调用JQueryDialog.Ok()函数,这个函数对应了用户提交事件. 2.用OO的概念来说,JQueryDialog.Ok()其实是一个虚函数,它的逻辑封装在子窗口ContentWindow.Ok()中,这一点我借鉴了FCKEditor,如下代码所示: JS代码 复制代码 代码如下: var JQueryDialog = { /// <summ

  • 简单的jQuery拖拽排序效果的实现(增强动态)

    增强动态增加Div效果 原来没有新建动作,分析代码后发现很容易增强~~ <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>测试的拖拽功能</title> <style type="text/css">

随机推荐