IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> react 拖拽实现一个穿梭框效果 -> 正文阅读

[JavaScript知识库]react 拖拽实现一个穿梭框效果

借鉴了网上大佬的一些文章,记录实现一个react的穿梭框的效果
实现拖拽效果的实现我们需要用到关于拖拽的事件,而在html5中刚好就有原生的拖拽api。

拖拽元素事件
dragstart 当一个元素开始被拖拽的时候触发
drag 这个事件在拖拽源触发
dragend 拖拽源在拖拽操作结束将得到dragend事件对象,不管操作成功与否

目标元素触发事件
dragenter 当拖拽中的鼠标第一次进入一个元素时触发
dragover 当拖拽中的鼠标移动经过一个元素时触发
dragleave 当拖拽中的鼠标离开元素时触发
drop 这个事件在拖拽操作结束释放时于释放元素上触发

需要注意:dragover事件下我们需要阻止浏览器的默认行为,让我们拖拽的元素成为可释放的元素。

而在我们拖拽元素的时候需要存储我们拖拽时携带的数据,这时候就用到了dataTransfer,他有两个方法:
一、setData()
1.第一个参数为携带数据的数据种类的字符串,只能填入类 似“text/plain”或“textml”的表示 MIME类型的文字
2.第二个参数为要携带的数据
二、getData()
1、目标元素接受到被拖放的元素后,执行getData()方法从DataTransfer里获取数据
2、getData()方法的参数为setData()方法中指定的数据类型

Demo:

const list = [
    {
        uid: '1',
        text: '序列1'
    },
    {
        uid: '2',
        text: '序列2'
    },
    {
        uid: '3',
        text: '序列3'
    },
    {
        uid: '4',
        text: '序列4'
    },
    {
        uid: '5',
        text: '序列5'
    },
]

const Drag = () => {
    const [rightList, setRightList] = useState(list)
    const [leftList, setLeftList] = useState([])
    
    //鼠标华划过接受拖拽元素的事件
    const handleDrop = (callBack, e, arrow) => {
        const {dataset:{id}}=e.target
        const curData = JSON.parse(e.dataTransfer.getData('itemData'))
        callBack(prevData => {
            const diffData = prevData.filter(item => item.uid !== curData.uid)
            // id 不存在是在不同盒子内拖拽  存在则是在本身盒子内拖拽
            if(!id) return [...diffData, curData]
             // 找到鼠标划过的目标元素的其盒子内的位置
             const index=diffData.findIndex(item=>item.uid===id)
            //把拖拽元素放置在鼠标划过元素的上方
            diffData.splice(index,0,curData)
            return diffData

        })
        //朝左拖拽
        if (arrow==='left') {
            setRightList(prvData => prvData.filter(item => item.uid !== curData.uid))
        }
        // 朝右拖拽
        else {
            setLeftList(prvData => prvData.filter(item => item.uid !== curData.uid))
        }
    }
     // 拖拽元素进入目标元素时触发事件-为目标元素添加拖拽元素进入时的样式效果
  const handleDragEnter = e => e.target.classList.add('over')

  // 拖拽元素离开目标元素时触发事件-移除目标元素的样式效果
  const handleDragLeave = e => e.target.classList.remove('over')

    return (
        <div>
            <div className='left'
                onDragOver={(e) => { e.preventDefault() }}
                onDrop={(e) => handleDrop(setLeftList, e, 'left')}
            >
                {
                    leftList.map(item => (
                        <div className='item'
                            draggable
                            key={item.uid}
                            data-id={item.uid}
                            onDragStart={(e) => { e.dataTransfer.setData('itemData', JSON.stringify(item)) }}
                        >{item.text}</div>
                    ))
                }
            </div>
            <div className='right'
                onDragOver={(e) => { e.preventDefault() }}
                onDrop={(e) => handleDrop(setRightList, e, 'right')}
                onDragEnter={handleDragEnter}
                onDragLeave={handleDragLeave}
            >
                {
                    rightList.map(item => (
                        <div className='item'
                            draggable
                            key={item.uid}
                            data-id={item.uid}
                            onDragStart={(e) => {
                                e.dataTransfer.setData('itemData', JSON.stringify(item))
                            }}
                        >{item.text}</div>
                    ))
                }
            </div>
        </div>
    )
}

export default Drag

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-03 10:40:34  更:2022-07-03 10:42:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/11 10:16:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码