Javascript写的一个可拖拽排序的列表

自己常试写了一个可拖拽进行自定义排序的列表,可能写的不太好,欢迎提供意见。

我的思路是将列表中的所有项都放进一个包裹层,将该包裹层设为相对定位,每当点击一个项时,将该项脱离文档并克隆一份重新添加到文档末尾并通过设置绝对定位让它出现在同样的位置,而原本在它后面的项则会因为它脱离文档而自动填充空位,当鼠标松开时通过鼠标的位置计算出当前位置处于列表的第几项,让后再将克隆项插入到该项之前。

 

 

完整代码:演示

css:

        #main {
            width: 500px;
            margin:0;
            padding: 0;
            background: blue;
            position: relative;
        }
        div.list{
            height: 50px;
            text-align: center;
            margin-top: 3px;
            background: lightblue;
        }
        div.list:first-child{
            margin-top: 0;
        }
        div.drag{    
            position: absolute;
            width: 500px;
            background: red;
            text-align: center;
            height: 50px;
            opacity: 0.5;
        }

样式部分最外层包层main需要将padding设为0并设为相对定位,如果需要有padding可以在main外面再包一层。

html:

    <div id="main">
        <div class="list">1</div>
        <div class="list">2</div>
        <div class="list">3</div>
        <div class="list">4</div>
        <div class="list">5</div>
    </div>

js:

        var div=g('#main');  //获取包裹层元素
        var mTop=div.offsetTop;  //包裹层距离顶端的位置

        var flag=0; //用于控制是否可拖拽
        var drag={    //保存克隆元素的一些信息
            curr: null,
            tTop: 0,
            num: 0
        };

        div.addEventListener('mousedown',function(e){ //添加mousedown事件
            flag=1; //当鼠标按下时,表示为可拖拽状态
            var curr=e.target;
            var top=(curr.offsetTop - mTop)+'px'; //当前元素相对于父元素的top值

            var y=e.pageY-curr.offsetTop;  //鼠标在当前项中的位置
            drag.tTop=y;  //记录y值
            console.log(top)
            var newDiv=div.removeChild(curr); //克隆当前项并移除
            newDiv.setAttribute('class','drag');  //添加样式
            newDiv.style.top=top;  //将位置定在当前位置
            newDiv.style.left=0;
            div.appendChild(newDiv);
            drag.curr=curr;
        });
        
        div.addEventListener('mousemove',function(e){ //利用鼠标移动事件模拟拖拽

            if(!flag){  //如果flag=0则不可拖拽
                return false;
            }else{
                
                var  curr=g('.drag')[0]; //获取克隆对象
                curr.style.top=(e.pageY-drag.tTop-mTop)+'px';    //通过鼠标位置改变克隆对象位置

                var ratio = (e.pageY - drag.tTop-mTop)%53;  //每个项的高度是固定的,所以可以通过当前高度除每个项的高度来确定要插入到那个项之前
                if(ratio<=5){ //设置偏差
                    curr.borderTop='2px solid green'; //添加提示
                    drag.num=Math.floor((e.pageY - drag.tTop - mTop)/53);
                    console.log(drag.num)
                }
            }
        });

        div.addEventListener('mouseup',function(e){ //拖放结束
            div.insertBefore(drag.curr,div.children[drag.num]); //插入
            drag.curr.setAttribute('class','list'); //添加样式
            drag.curr.style=null; //清除样式
            flag=0;
        })
        function g(str){  //用于方便获取元素对象
            if(/^#.+/.test(str)){
                str=str.slice(1);
                return document.getElementById(str);
            }else if(/^\..+/.test(str)){
                str=str.slice(1);
                return document.getElementsByClassName(str);
            }else {
                return document.getElementsByTagName(str);
            }
        }

 

posted @ 2017-10-05 18:10  法克大叔叔  阅读(520)  评论(0编辑  收藏  举报