vue移动端拖动排序

vue移动端拖动排序

前言

我们移动端排序,如果使用drag拖动事件会有重影,在移动端会显得不是很友好,还是需要控制dom的位置去实现。效果自己复制代码运行就可以看到效果;

一、直接上代码

<template>
    <div class="old_sort_main">
        <div class="show_func">已显示功能</div>
        <!--下面是一个容器-->
        <div id="sort_content"></div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            funcManager: ['转账', '生活缴费', '存款产品', '客户经理', '我的账户','未显示功能', '账户明细','设置'],
            domHeight: 50,
            children: [],
            target: null,
            moveTop: 0,
            targetNum: 0
        }
    },
    mounted() {
        // 这是一个渲染函数
        this.render(this.funcManager);
        // 内部函数的this不是指向vue实例
         let _this = this;
        // 鼠标松开设置最终落下位置
        document.ontouchend = function() {
            // 解绑ontouchmove函数
            document.ontouchmove = null
            if (!_this.target) return null
            const nowNum = Math.round(_this.moveTop / _this.domHeight)
            if (nowNum >= _this.children.length - 1) {
            _this.target.style.top = (_this.children.length - 1) * _this.domHeight + 'px'
            } else if (nowNum <= 0) {
            _this.target.style.top = '0px'
            } else {
            _this.target.style.top = nowNum * _this.domHeight + 'px'
            }
            var arr = [];
            for(let i =0; i < document.getElementsByClassName('item').length; i++) {
                let index = (document.getElementsByClassName('item')[i].style.top.split('px')[0]/_this.domHeight);
                let val = document.getElementsByClassName('item')[i].children[0].outerText;
                arr[index] =  val;
            }
            for(let i =0; i < document.getElementsByClassName('drag').length; i++) {
                document.getElementsByClassName('drag')[i].ontouchend = null;
            }
            document.getElementById('sort_content').innerHTML = '';
            console.log(102012, arr)
            _this.render(arr);
            _this.moveTop = 0
            _this.targetNum = 0
        }
    },
    methods: {
        render(list) {
            let root = document.getElementById('sort_content');
            root.style.height = list.length * this.domHeight + 'px';
            this.children = [];
            // 循环插入节点
            for (let i = 0, len = list.length; i < len; i++) {
                let item = '<span class="dragValue">' + list[i] + '</span>'
                if(list[i] === '未显示功能') {
                    item = '<span class="ston">' + list[i] + '</span>' 
                }
                const div = document.createElement('div')
                div.className = 'item'
                // const span = document.createElement('img')
                // span.src = require('@/assets/images/oldVersion/more_old.png')
                const span = document.createElement('span')
                span.className = 'drag'
                // if(list[i] === '未显示功能') {
                //     span.className = 'undrag'
                // }
                if(list[i] === '未显示功能') {
                    span.className = 'undrag'
                } else {
                    span.innerHTML = '可拖动部分'
                }
                div.innerHTML = item
                div.appendChild(span)
                div.style.top = i * this.domHeight + 'px'
                div.style.height = this.domHeight + 'px'
                this.children.push(div)
                // 插入到排序根节点
                root.appendChild(div)
                // 给拖拽部分添加拖拽事件
                this.domDrag(span, i)
            }
        },
        // 拖拽
        domDrag(span, i) {
            let timer;
            let flag = false;
            let _this = this;
            span.ontouchstart = function(e) {
            // 控制长按时间
            timer = setTimeout(() => {
                flag = true;
            }, 200)
            const top = e.touches[0].clientY - span.parentNode.offsetTop
            _this.target = span.parentNode;
            _this.targetNum = Math.round(span.parentNode.offsetTop / _this.domHeight)
            _this.target.style.top = i*_this.domHeight +'px'
            _this.moveTop = i*_this.domHeight;
            document.ontouchmove = function(e) {
                    if(!flag) {
                        return;
                    }
                    _this.moveTop = e.touches[0].clientY - top
                    _this.target.style.top = _this.moveTop +'px'
                    _this.target.style.boxShadow = '0px 0px 5px #888888';
                    _this.target.style.zIndex = '1000';
                    _this.domMove();
                }
            }
            span.ontouchmove = function() {
                clearTimeout(timer);
            }
            span.ontouchend = function() {
                clearTimeout(timer);
            }
        },
        // 交换位置
        domMove() {
            const nowNum = Math.round(this.moveTop / this.domHeight)
            for (let i = 0, len = this.children.length; i < len; i++) {
                const item = this.children[i]
                if (this.target === item) {
                    continue
                }
                const itemNum = parseInt(item.style.top) / this.domHeight
                if (itemNum === nowNum) {
                    if (itemNum < this.targetNum) {
                    item.style.top = parseInt(item.style.top) + this.domHeight + 'px'
                    } else if (itemNum > this.targetNum) {
                    item.style.top = parseInt(item.style.top) - this.domHeight + 'px'
                    }
                    this.targetNum = Math.round(this.moveTop / this.domHeight)
                    return null
                }
            }
        }
    },
}
</script>

<style lang="stylus" scoped>
.old_sort_main {
    position relative
    .show_func {
        width: 100%;
        left: 0;
        height: 106px;
        line-height: 106px;
        text-indent: 32px;
        font-size: 36px;
        color: #999999;
        background-color: #E5E5E5;
    }
    .dragValue {
        font-size: 36px;
        color: #333333
    }
}
</style>
<style>
#sort_content {
    position: absolute;
    width: 100%;
    background-color: #ffffff;
}
.old_sort_main {
    font-size: 36px;
}
.old_sort_main .dragValue {
    font-size: 36px;
    color: #333333
}
.old_sort_main .drag {
    margin-right: 32px;
}
.old_sort_main .undrag {
    display: none;
}
.old_sort_main .item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    text-indent: 32px;
    background-color: #ffffff;
}
.old_sort_main .ston {
    height: 106px;
    width: 100%;
    line-height: 106px;
    text-indent: 32px;
    font-size: 36px;
    color: #999999;
    background-color: #E5E5E5;
}
.old_sort_main .item {
    width: 100%;
    position: absolute;
    left: 0;
    display: flex;
    align-items: center;
}
</style>

2.运行效果如下

![!](https://img-blog.csdnimg.cn/20210615163914982.jpg)

总结

效果自己复制代码运行就可以看到效果;

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值