分享一个多拽更改列表序列的代码 (JQuery+Vue)

这周公司要求我去调研一下腾讯问卷系统的编辑问卷实现的功能

对于一个前端er 来说,去研究别人的前端交互是很有热情的。当中除了一些简单的css 样式在短时间内是可以模仿出来,除了拖拽改变序列让我沉思了比较久的时间,其他都很快就弄通透了。

那么就开始吧

首先,我使用的JQuery+Vue 来完成的

第一是我需要一个能帮我完成数据绑定的框架,第二个是我需要对DOM进行大量操作才能完成拖拽改变序列这一工作。

既然要实现拖动,并且要有一个好看的动画效果,首先我就把 drag事件给否认了。

我心目中最合适的就是 mousedown , mousemove, mouseup了

我在每个div 中 都绑定了一个mousedown 事件,并且当mousedown触发时 随之绑定 document 的 mousemove 与  mouseup 事件, 只有当用户 触发mouseup  才注销掉 mousemove 与 mouseup 的 事件

我的处理方式是将需要遍历的数组 做一个备份, 每当我们拖拽(mousedown&mousemove)某一个元素时,就深拷贝一个备份数组,并将当中的对应拖拽元素删去,然后根据拖动的高度,添加到对应的index 中,并将排序好的数组赋值给遍历数组,完成预览效果, 当用户触发mouseup时 将遍历数组赋值给拷贝数组,就完成了拖拽排序啦!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>drag</title>
    <script src="./vue.js"></script>
    <script src="jquery.js"></script>
    <style>
        * {
            padding: 0;
            margin: 0;
            user-select: none;
        }

        .item:nth-child(even) {
            background: #EFEFEF;
        }

        .item:nth-child(odd) {
            background: #e0e0e0;
        }

        .item {
            width: 200px;
            height: 50px;
            padding: 5px;
        }

        .item-mask {
            position: absolute;
            left: 0;
            width: 200px;
            height: 50px;
            padding: 5px;
            background: yellow;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="item" v-for="(item,index) in message" v-show="index!=0" @mousedown="down($event,index)">
        {{item}}
    </div>
    <div class="item-mask" :style={top:curTop+'px'} v-if="curItem!=''" v-show="show">{{curItem}}</div>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            message: ['', 1, 2, 3, 4, 5, 6],
            bakmessage: ['', 1, 2, 3, 4, 5, 6],
            show: false,
            curItem: '',
            heightArr: [],
            curTop: 0
        },
        created() {
            this.initHeight();
        },
        methods: {
            down(evt, idx) {
                let me = this;
                this.curItem = this.message[idx];
                this.curTop = $('.item').eq(idx).position().top;
                this.show = true;
                var offsetY = evt.layerY;

                $(document).on('mousemove', function (e) {
                    me.move(e, idx, offsetY)
                });
                $(document).on('mouseup', function (e) {
                    me.up(e)
                });

            },
            move(e, index, offsetY) {
                var bak = deepCopy(this.bakmessage);
                let me = this;
                let relY = e.clientY - offsetY + 60 * (index-1);
                this.curTop = relY;
                console.log(relY)
                this.heightArr.map(function (item, i, arr) {

                    if (me.curTop > item && me.curTop < arr[i + 1]) {
                        bak.splice(index, 1);
                        bak.splice(i + 1, 0, me.curItem)
                        me.message = bak;
                    }
                });
            },
            up(e) {
                this.show = false;
                this.bakmessage = this.message;
                $(document).unbind('mousemove')
            },
            initHeight() {
                let arr = [];
                this.$nextTick(function () {
                    this.message.map(function (item, index) {
                        var top = $('.item').eq(index).position().top;
                        arr.push(top + 60)
                    });
                    this.heightArr = arr;
                    this.heightArr.unshift(-30)
                    this.heightArr.push(390)
                })

            }
        }
    })

    function isArr(obj) {        // 检验该对象是不是数组
        return Object.prototype.toString.call(obj) === '[object Array]'
    }

    function deepCopy(obj) {
        var newObj = isArr(obj) === true ? [] : {};
        for (let item in obj) {
            if (typeof obj[item] === 'object') {
                newObj[item] = deepCopy(obj[item])
            } else {
                newObj[item] = obj[item]
            }
        }
        return newObj
    }

</script>
</html>

代码复制了,就可以看,这个是我个人做的一个demo,可以参考着使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值