原生JS实现拖拽排序的示例代码

 更新时间:2022年12月07日 14:15:35   作者:你也向往长安城吗  
说到拖拽,应用场景不可谓不多。无论是打开电脑还是手机,第一眼望去的界面都是可拖拽的,靠拖拽实现APP或者应用的重新布局,或者拖拽文件进行操作文件。本文就将利用JS实现拖拽排序,需要的可以参考一下

说到拖拽,应用场景不可谓不多。无论是打开电脑还是手机,第一眼望去的界面都是可拖拽的,靠拖拽实现APP或者应用的重新布局,或者拖拽文件进行操作文件。

先看效果图,如何实现一个如图HTML元素的拖拽并排序

HTML中的拖拽事件(drag & drop)

参考MDN中文文档

事件类型

  • drag : 当拖拽的元素或者选中的文本时触发
  • dragend : 当拖拽元素结束时触发
  • dragenter : 当拖拽元素或选中的文本到一个可释放目标时触发
  • dragleave : 当拖拽元素或选中的文本离开一个可释放目标时触发
  • dragover : 当元素或选中的文本被拖到一个可释放目标上时触发(每 100 毫秒触发一次)
  • dragstart : 当用户开始拖拽一个元素或选中的文本时触发
  • drop : 当元素或选中的文本在可释放目标上被释放时触发

Coding

写一段简单的CSS和html ,实现初始的页面

        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        ul{
            margin: 200px auto;
            width: 200px;
            list-style-type: none;
        }
        li{
            margin: 5px;
            text-align: center;
            width: 200px;
            height: 30px;
            background: skyblue;
        }
        .list .moving{
            background: transparent;
            color: transparent;
            border: 1px dashed #ccc;
        }  
    <ul class="list">
        <li >1</li>
        <li >2</li>
        <li >3</li>
        <li >4</li>
        <li >5</li>
    </ul>

此时我们的页面如下图

现在还不可以进行拖拽操作,为了可以实现拖拽操作,我们必须给每个元素设置 draggable="true"

    <ul class="list">
        <li draggable="true">1</li>
        <li draggable="true">2</li>
        <li draggable="true">3</li>
        <li draggable="true">4</li>
        <li draggable="true">5</li>
    </ul>

元素已经可以基础的拖拽

image.png

接下来我们需要在JS中对DOM元素进行一系列操作来实现对应的效果

  • 实现拖出去的元素,原位置样式变为透明虚线
  • 实现拖动到其他元素上时,列表顺序发生改变
        let list = document.querySelector('.list')
        let currentLi      // 记录拖拽元素

我们用事件委托,监听 "dragstart" 事件,给拖动的元素添加类名,修改样式,这里会出现奇怪的一幕就是,拖动的样式和原来的样式同时变成了透明。

        list.addEventListener('dragstart',(e)=>{
            e.dataTransfer.effectAllowed = 'move'   // 拖动样式改为 "move"
            currentLi = e.target  
            currentLi.classList.add('moving')
        })

这里会出现奇怪的一幕就是,拖动的样式和原来的样式同时变成了透明。这是因为跟随鼠标拖动的元素的样式在拖动的那一刻是原始元素的样式,所以也会添加"moving", 那么在这里我们加一个异步

        list.addEventListener('dragstart',(e)=>{
            e.dataTransfer.effectAllowed = 'move'
            currentLi = e.target
            setTimeout(()=>{
                currentLi.classList.add('moving')
            })
        })

到这里距离目标又更近了一步,

接下来我们需要在拖动的过程中对列表的元素进行重新的排序

Node.insertBefore():方法在参考节点之前插入一个拥有指定父节点的子节点

        list.addEventListener('dragenter',(e)=>{
            e.preventDefault()  // 阻止默认事件
            if(e.target === currentLi||e.target === list){   // 当移动到当前拖动元素,或者父元素上面我们不做操作
                return
            }
            let liArray = Array.from(list.childNodes)
            let currentIndex = liArray.indexOf(currentLi)   // 获取到拖动元素的下标
            let targetindex = liArray.indexOf(e.target)     // 获取到目标元素的下标

            if(currentIndex<targetindex){
                list.insertBefore(currentLi,e.target.nextElementSibling)
            }else{
                list.insertBefore(currentLi,e.target)
            }
        })

最后我们需要在拖拽结束将元素的moving类名移除,以及阻止拖拽到一个目标上的默认事件(否则会出现禁止)

        list.addEventListener('dragover',(e)=>{
            e.preventDefault()
        })
        list.addEventListener('dragend',(e)=>{
            currentLi.classList.remove('moving')
        })

至此,一个简单的拖拽排序功能就实现了

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        ul{
            margin: 200px auto;
            width: 200px;
            list-style-type: none;
        }
        li{
            margin: 5px;
            text-align: center;
            width: 200px;
            height: 30px;
            background: skyblue;
        }
        .list .moving{
            background: transparent;
            color: transparent;
            border: 1px dashed #ccc;
        }  
        </style>
</head>
<body>
    <ul class="list">
        <li draggable="true">1</li>
        <li draggable="true">2</li>
        <li draggable="true">3</li>
        <li draggable="true">4</li>
        <li draggable="true">5</li>
    </ul>

    <script>
        let list = document.querySelector('.list')
        let currentLi
        list.addEventListener('dragstart',(e)=>{
            e.dataTransfer.effectAllowed = 'move'
            currentLi = e.target
            setTimeout(()=>{
                currentLi.classList.add('moving')
            })
        })

        list.addEventListener('dragenter',(e)=>{
            e.preventDefault()
            if(e.target === currentLi||e.target === list){
                return
            }
            let liArray = Array.from(list.childNodes)
            let currentIndex = liArray.indexOf(currentLi)
            let targetindex = liArray.indexOf(e.target)

            if(currentIndex<targetindex){
     
                list.insertBefore(currentLi,e.target.nextElementSibling)
            }else{
      
                list.insertBefore(currentLi,e.target)
            }
        })
        list.addEventListener('dragover',(e)=>{
            e.preventDefault()
        })
        list.addEventListener('dragend',(e)=>{
            currentLi.classList.remove('moving')
        })
    </script>
</body>
</html>

以上就是原生JS实现拖拽排序的示例代码的详细内容,更多关于JS拖拽排序的资料请关注脚本之家其它相关文章!

相关文章

  • JS实现从表格中动态删除指定行的方法

    JS实现从表格中动态删除指定行的方法

    这篇文章主要介绍了JS实现从表格中动态删除指定行的方法,通过getElementById获取指定行再使用deleteRow方法来实现删除行的功能,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • JavaScript中的scrollTop详解(滚动到顶部)

    JavaScript中的scrollTop详解(滚动到顶部)

    scrollTop是JavaScript中一个非常有用且重要的方法,它用于获取或设置元素的垂直滚动条位置,这篇文章主要给大家介绍了关于JavaScript中scrollTop详解(滚动到顶部)的相关资料,需要的朋友可以参考下
    2023-12-12
  • javascript实现全角转半角的方法

    javascript实现全角转半角的方法

    这篇文章主要介绍了javascript实现全角转半角的方法,涉及JavaScript字符串遍历与编码转换的相关技巧,需要的朋友可以参考下
    2016-01-01
  • JavaScript实现简单获取当前网页网址的方法

    JavaScript实现简单获取当前网页网址的方法

    这篇文章主要介绍了JavaScript实现简单获取当前网页网址的方法,通过location对象的href方法来获取网址,非常简单实用,需要的朋友可以参考下
    2015-11-11
  • JavaScript常用脚本汇总(二)

    JavaScript常用脚本汇总(二)

    本文给大家分享的javascript常用脚本有把JavaScript中的伪数组转换为真数组、JavaScript设置主页功能、JavaScript收藏功能、javascript检测元素是否支持某个属性代码、创建和使用命名空间,有需要的小伙伴们快来看看吧。
    2015-03-03
  • 微信小程序在Tab的icon上显示消息数量的方法

    微信小程序在Tab的icon上显示消息数量的方法

    这篇文章主要介绍了微信小程序在Tab的icon上显示消息数量的方法,首先,在app.json文件中,找到对应的tabBar配置,本文通过示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • js获取隐藏元素宽高的实现方法

    js获取隐藏元素宽高的实现方法

    下面小编就为大家带来一篇js获取隐藏元素宽高的实现方法。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • JavaScript和JQuery的鼠标mouse事件冒泡处理

    JavaScript和JQuery的鼠标mouse事件冒泡处理

    这篇文章主要介绍了JavaScript和JQuery的鼠标mouse事件冒泡处理,本文总结出了mouse事件的一些定论,并分别给出了JavaScript和JQuery测试代码,需要的朋友可以参考下
    2015-06-06
  • 微信小程序获取当前位置和城市名

    微信小程序获取当前位置和城市名

    这篇文章主要介绍了微信小程序获取当前位置和城市名的思路,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • 前端如何实现动画过渡效果

    前端如何实现动画过渡效果

    这篇文章主要介绍了前端如何实现动画过渡效果,帮助大家更好的理解和学习前端开发网页,感兴趣的朋友可以了解下
    2021-02-02

最新评论