zoukankan      html  css  js  c++  java
  • jquery 拖拽排序分析

      今天应一个朋友的委托,研究一下拖拽排序,我记得我上次写拖拽排序,因为方法太死板,效果我一直不是很满意,一直想再从写一个,一直没机会(懒),这次因为公司部门变动所以有了一些时间(无聊)来写,本来准备使用Vue写,奈何功夫不到家在自定义指令的时候,问题卡住了,研究了一段时间之后,还是决定放弃,研究一下Vue再来写过,所以本次还是用了Jquery来写。

      

      直接上代码

      这是CSS部分

     1     *{/*Css*/
     2             margin: 0px;
     3             padding: 0px;
     4             list-style: none;
     5             text-decoration: none;
     6             border: none;
     7             color: #000;
     8             text-shadow: none;
     9             box-shadow: none;
    10             outline: none
    11         }
    12        button, ul {
    13             margin-left: 20px;
    14         }
    15         ul li{
    16             background: #AAABCA;
    17             margin: 3px 0px;
    18             width: 200px;
    19             overflow: hidden;
    20         }
    21         ul li span{
    22             float: right;
    23             padding: 0px 3px;
    24         }
    25         ul li.on{
    26             height: 50px;
    27         }
    28         ul li span:hover{
    29             background: #ccc;
    30             cursor: pointer;
    31         }
    32         button{
    33             padding: 10px;
    34             cursor: pointer;
    35         }

        HTML部分   

    1 <button id="add">add</button>
    2 <ul class="list">
    3     <li>item1 
    4         <span class="remo">X</span>
    5         <span class="goUp">^</span>
    6         <span class="goDown">V</span>
    7     </li>
    8 </ul>

        Js部分

       

      1 $(function(){
      2         //---------
      3         Array.prototype.min = function() {
      4         var min = this[0];
      5         var index = 0;
      6         var len = this.length;
      7         for (var i = 1; i < len; i++){
      8             if (this[i] < min){
      9                 min = this[i];
     10             }
     11         } 
     12         return min;
     13         }
     14         //---------
     15         var i = $('.list').find('li').length;
     16         var cls = 'on';
     17         $('#add').click(function(){
     18             i++;
     19             cls = cls?false:'on';
     20             $('.list').append('<li class="'+cls+'">item'+i+' <span class="remo">X</span><span class="goUp">^</span><span class="goDown">V</span></li>');
     21             addmous();
     22 
     23         });
     24         addmous();
     25         var keyf = true;//变量控制第一次拖拽结束前,不允许其他操作
     26         function addmous(){
     27             $('.remo').off('mousedown').on('mousedown',function(){//绑定删除元素
     28                 keyf = false;
     29                 $(this).parent().remove();
     30             });
     31             $('.goUp').off('mousedown mouseup').on({'mousedown':function(){//向上按钮
     32                 keyf = false;
     33                 return false;
     34             },'mouseup':function(){
     35                 let $this = $(this).parent();
     36                 let prev =  $this.prev();
     37                 $this.after(prev);
     38                 keyf = true;
     39             }});
     40             $('.goDown').off('mousedown mouseup').on({'mousedown':function(){//向下按钮
     41                 keyf = false;
     42             },'mouseup':function(){
     43                 let $this = $(this).parent();
     44                 let prev =  $this.next();
     45                 $this.before(prev);
     46                 keyf = true;
     47                 return false;
     48             }});
     49             $('.list li').off('mousedown').on({'mousedown':moused,'mouseover':function(){
     50                 return false;
     51             }});//绑定mousedown事件
     52             var scrollLength = null;
     53             function moused(ev){            //mousedown
     54                 if(keyf == false){return};//如果之前还有未完成的操作,那么return
     55                 keyf = false;
     56                 scrollLength = $(window).scrollTop() - 20;//保持滚动之后,不会错位,为了优化显示效果,减去20
     57                 var allTop = [];
     58                 var allLi = $('.list').find('li');
     59                 for(var i = 0 ; i < allLi.length ; i++){//拿到ul当中所有li距离顶部的距离
     60                     allTop.push(allLi.eq(i).offset().top);
     61                 }
     62                 var _this = $(this);
     63                 var l = $(this).offset().left;
     64                 var t = $(this).offset().top - 3;
     65                 let mX = ev.clientX,
     66                     mY = ev.clientY + scrollLength,
     67                     disX = mX - l,    //确定鼠标按下的位置
     68                     disY = mY - t;
     69                 $(this).css({'position': 'absolute','left':l +'px','top':t +'px'});//将点击元素从不同文档流中的元素,变成定位元素
     70                 var html = $(this).html();//拿到当前元素的 内容和class,复制成影子
     71                 var aCls = $(this).attr('class');
     72                 $(this).after('<li class="addLi '+aCls+'" style="opacity:.4">'+html+'</li>');
     73                 $(document).on({'mousemove':mousem,'mouseup':mouseu});
     74                 //将move,up事件,绑定在document身上,防止快速拖拽容易丢失的问题
     75                 function mousem(ev){          //mousemove
     76                     keyf = false;
     77                     var setArr = [];
     78                     scrollLength = $(window).scrollTop() - 20; //解决滚动条问题
     79                     let mX = ev.clientX,
     80                         mY = ev.clientY + scrollLength,//鼠标距离加上滚动的距离,防止滚动之后错位
     81                         l = mX - disX;
     82                         t = mY - disY;
     83                     _this.css({'left':l+'px','top':t+'px'})//修改left,top形成拖拽
     84                     for(var i = 0 ;i < allTop.length ; i++){//循环之前拿到的所有Li的top数组
     85                         var zo = mY - allTop[i];  //使用鼠标的top,减去所有的li的top,(也就是鼠标到所有li的距离)
     86                         setArr.push(zo < 0?zo*-1:zo); //所有距离转化成正数
     87                     }
     88                     var arrMin = setArr.min();//拿到鼠标到所有li的距离中的最小数(离鼠标最近li)
     89                     var minIndex = setArr.indexOf(arrMin,0);//查找距离鼠标最近的li的下标
     90                     var allLi2 = $('.list').find('li');
     91                     if(minIndex == 0){//如果距离鼠标最近的是第一个
     92                         mY < allLi2.eq(0).offset().top ? allLi2.eq(0).before($('.addLi')):allLi2.eq(0).after($('.addLi'));
     93                         //再判断鼠标的的位置在不在第一个元素的上面,在上面,就往li[0]的前面插入,否则在后面插入
     94                     }else if (minIndex == allTop.length -1){
     95                         //最后一个元素,和第一个道理一样,写法相反
     96                         mY > allLi2.eq(allTop.length).offset().top ? allLi2.eq(allTop.length).after($('.addLi')):allLi2.eq(allTop.length).before($('.addLi'));
     97                     }else{
     98                         //中间元素
     99                         allLi2.eq(minIndex).after($('.addLi'));//将影子插入到 距离鼠标最近li的后面
    100                     }
    101                 }
    102                 function mouseu(){         //mouseup
    103                     var ol = $('.addLi').offset().left;//拿到影子元素的坐标
    104                     var ot = $('.addLi').offset().top;
    105                     $(document).off({'mousemove':mousem,'mouseup':mouseu});//将拖拽元素的left,top变化到影子的目标坐标上
    106                     _this.animate({'left':ol,'top':ot - 3},function(){//减3,是为了优化视觉效果
    107                         _this.css('position','static');//取消定位
    108                         $('.addLi').after(_this);//将目标元素插入到影子元素后面
    109                         $('.addLi').remove();//删除影子元素
    110                         keyf = true;//结束动作
    111                     })
    112                 }
    113                 return false
    114             }
    115             
    116         }
    117         
    118     })

       嗯,其中的原理,我认为在注释当中写的比较详细了,本身难度没有特别高,主要的思路就是:先把多个Li的offsetTop存成数组allTop,然后使用鼠标的Top值,减去allTop的每一项,生成新的数组setArr,setArr就是所有Li距离鼠标的距离,找到其中最小的值,就是距离鼠标最近的,然后找到最小值得在数组中的下标,也就是对应的dom元素Li在的下标,找到最近的Li之后,插入影子元素即可,主要在onmousemove,中的判断影子元素位置的地方,对数组的操作,需要注意的还有,当产生滚动条的时候,需要吧滚动距离给加上,否则会错位。

          不说了,我得去找工作了,加油!

          以上

          2017-04-26  击鼓卖糖

  • 相关阅读:
    PNG文件格式具体解释
    opencv2对读书笔记——使用均值漂移算法查找物体
    Jackson的Json转换
    Java实现 蓝桥杯VIP 算法训练 装箱问题
    Java实现 蓝桥杯VIP 算法训练 装箱问题
    Java实现 蓝桥杯VIP 算法训练 单词接龙
    Java实现 蓝桥杯VIP 算法训练 单词接龙
    Java实现 蓝桥杯VIP 算法训练 方格取数
    Java实现 蓝桥杯VIP 算法训练 方格取数
    Java实现 蓝桥杯VIP 算法训练 单词接龙
  • 原文地址:https://www.cnblogs.com/dongwy/p/6767610.html
Copyright © 2011-2022 走看看