原生js实现拖拽改变元素顺序

代码展示如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            border: 10px solid #000;
        }
        .item{
            margin: 10px 10px 0 10px;
            background-color: aquamarine;
            padding: 10px;
            text-align: center;
        }
        .item:nth-last-child(1){
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="box">
    </div>
    <h1></h1>
    <script>
        class Demo {
            constructor(data,box,showResBox){
                this.data = data
                this.box = box
                this.showResBox = showResBox
                this.init(data,box,showResBox)
            }
            init (data,box) {
                let fragment = document.createDocumentFragment();
                for (let i = 0; i < data.length; i++) {
                    let div = document.createElement("div")
                    div.setAttribute("class","item")
                    div.setAttribute("draggable",true)
                    div.innerText = data[i]
                    fragment.appendChild(div)
                }
                box.appendChild(fragment)
                this.showResBox.innerHTML = `最终的结果:${data.join('-')}`
                this.handledragstart(box)
                this.handledragover(box)
                this.handledragend(box)
                fragment = null
            }
            changeElemPosition(source,target,parentNode) {
                let sourceNext = source.nextSibling;
                let targetNext = target.nextSibling;
                parentNode.insertBefore(target,sourceNext)
                parentNode.insertBefore(source,targetNext)
            }
            eventFn(e) {
                let that = this
                switch (e.type) {
                    case 'dragstart':
                        if (e.target.className=="item") {
                            that.sourceElem = e.target
                        }
                        return
                    case 'dragover':
                        e.preventDefault()
                        if (e.target.className=="item") {
                            that.targetElem = e.target
                        }
                        return
                    case 'dragend':
                        let temp = []
                        that.changeElemPosition(that.sourceElem,that.targetElem,e.currentTarget)
                        Array.from(e.currentTarget.children).forEach(elem=>{
                            temp.push(Number(elem.innerText)) 
                        })
                        that.data = [...temp]
                        that.showResBox.innerHTML = `最终的结果:${that.data.join('-')}`
                        that.removeEventAndObj(that.eventFn)
                        return
                }
            }
            handledragstart (box) {
                box.addEventListener('dragstart',(e)=>{this.eventFn(e)})
            }
            handledragover (box) {
                box.addEventListener('dragover',(e)=>{this.eventFn(e)})
            }
            handledragend (box) {
                box.addEventListener('dragend',(e)=>{this.eventFn(e)})
            }
            removeEventAndObj(eventFn) {
              this.targetElem = null
              this.sourceElem = null
              this.box.removeEventListener('dragstart',eventFn)
              this.box.removeEventListener('dragover',eventFn)
              this.box.removeEventListener('dragend',eventFn)
            }

        }
        let d = new Demo([1,2,3,4,6],document.querySelector('.box'),document.querySelector('h1'))
    </script>
</body>
</html>

效果展示如下:

在这里插入图片描述

知识点须知:【详情请参考:insertBefore

Node.insertBefore(newNode,referenceNode)

如果给定的节点(newNode)是对文档中现有节点的引用,insertBefore方法会将其从当前位置移动到新位置将节点附加到其他节点之前的操作,不需要从其父节点删除该节点)。

用法:

parentNode.insertBefore(newNode, referenceNode);

需要注意的是:html5 draggable属性在移动端不生效

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值