0
点赞
收藏
分享

微信扫一扫

JS 实现拖拽之 - 列表拖拽

Mezereon 2021-09-24 阅读 172

这次的列表拖拽模型主要模仿的就是简书后台写文章里面的功能。上个例子九宫格拖拽只是这次的一个例外。研究完上个模型再写这个就更简单了,随便划拉两下就完成了。

实现的思路:

依然是以拖拽模型为基础,相对于九宫格拖拽,这个加入了过渡动画,并且让交换盒子动作发生在移动事件之中。这时候就得把移动盒子的位置单独拿出来,放在鼠标抬起事件结束的地方。另外值得注意的地方,必须的加一个锁,为什么呢?原因好简单,当我们移动的时候,满足条件的时候,另一个盒子就会发生改变,假如移动的方向是往上的,盒子改变的过程有时间过渡,这时候我们移动的盒子还没完全离开盒子,这时候又满足判断条件,盒子反向运动,又回来了。加一个锁让本次盒子运动完成之后在打开锁进行运动。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>列表拖拽模型</title>
    <style>
        *{margin:0;padding:0;}
        body{
            background-color: #000;
        }
        ul{
            list-style:none;
            height: 850px;
            width: 400px;
            border-radius: 5px;
            margin:20px auto;
            position: relative;
            border:1px solid red;
        }
        ul li {
            position: absolute;
            width: 400px;
            height: 100px;
            background-color: #fff;
            border-radius: 10px;
            margin-top: 10px;
            box-shadow: 1px 1px 1px #07c160;
            cursor:pointer;
        }
        h3{
            width: 400px;
            line-height: 100px;
            text-align:center;
            color:#07c160;
            font-size: 24px;
        }
        /*拖拽的时候让拖拽的图片置于其他图片上面*/
        .active{
            z-index: 1;
        }
    </style>
</head>
<body>
    <ul>
        <li><h3>第一张</h3></li>
        <li><h3>第二张</h3></li>
        <li><h3>第三张</h3></li>
        <li><h3>第四张</h3></li>
        <li><h3>第五张</h3></li>
        <li><h3>第六张</h3></li>
    </ul>
</body>
</html>
<script>
    //得到元素
    var uls = document.querySelector("ul");
    var lis = uls.querySelectorAll("li");

    // 批量添加监听
    for(var i = 0;i < lis.length;i++){
         // 批量放置li盒子
        lis[i].style.top = i * 105 + "px";
        // 闭包的影响属性法备份每个监听事件的i
        lis[i].index = i;
        lis[i].onmousedown = function(event){
            // 兼容IE
            event = event || window.event;

            // 鼠标到每个li盒子内层最顶端和最左端的位置
            var lisx = event.clientX - this.offsetLeft;
            var lisy = event.clientY - this.offsetTop;
            // 备份this
            var self = this;
            // 一个锁,防止事件重复触发
            var lock = true;
            // 鼠标移动
            document.onmousemove = function(event){
                // 移除掉每个触发li的transition动作
                self.style.transition = "";
                // 兼容IE
                event = event || window.event;
                // li盒子到它的offsetparent的距离,就是离li最近定位的盒子
                lisL = event.clientX - lisx;
                lisT = event.clientY - lisy;
                // 拖拽的时候让拖拽的图片置于其他图片上面更改图片的显示权重
                self.className = "active";
                //改变移动盒子的定位,做到鼠标跟随
                self.style.left = lisL + "px";
                self.style.top = lisT + "px";
                // 批量遍历每个盒子是否满足交换条件
                for(var j = 0;j < lis.length;j++){
                    // 交换盒子的条件
                    if(lis[j].offsetTop + lis[j].offsetHeight > self.offsetTop && lis[j].offsetTop < self.offsetTop){
                        if(lock){
                            // 事件触发就自锁不在改变
                            lock = false;
                            // console.log(self.index);
                            // 交换两个盒子备份的index
                            var temp = lis[j].index;
                            lis[j].index = self.index;
                            self.index = temp;
                            // 交换完成去改变盒子的top值
                            lis[j].style.top = lis[j].index * 105 + "px";
                            // 同时添加过渡属性
                            lis[j].style.transition = "all 0.3s ease 0s";
                            // 当动画运动完成,使用定时器来打开锁。
                            setTimeout(()=>lock = true,300);
                            break;
                        }
                    }
                }
            }
            // 鼠标抬起事件
            document.onmouseup = function(event){
                // 移出鼠标移动事件
                document.onmousemove = null;
                // 去除图片显示权重
                self.className = "";
                // 改变移动盒子的位置
                self.style.left = 0;
                self.style.top = self.index * 105 + "px";
            }
            // 阻止浏览器的默认事件
            return false;
        }
    }
</script>
举报

相关推荐

0 条评论