0
点赞
收藏
分享

微信扫一扫

虹科方案 | AR助力仓储物流突破困境:规模化运营与成本节约

at小涛 2023-10-12 阅读 44

文档

一、被拖拽元素和放置被拖拽元素的元素

1.1 被拖拽元素

将 HTML 元素的 draggable 属性设置为 true, 元素就可以变为可拖拽元素。效果如下图。

<div id="box" draggable="true">draggable box</div>

在这里插入图片描述

1.2 可放置被拖拽元素的元素

默认情况下是这样:

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>

在这里插入图片描述
设置为放置区域需要给元素绑定一个事件 dragover 且要 阻止默认行为

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
</script>

React:
放置区域需要绑定onDragOver事件,且要 阻止默认行为 – 其他事件一样加on

<div draggable="true">draggable box</div>
<div onDragOver={(e) => {e.preventDefault()}}>放置区域</div>

设置为可放置区域后鼠标样式也变了不再是禁止图标,而是一个加号图标(图标可以设置,下面会讲解):
在这里插入图片描述
然而你会发现被拖放元素并没有真正的被放置到放置区域,这是必然的,放置操作需要开发者自行定义,以上的设置只是是为了向用户表明这个区域是允许放东西的,那么至于怎么放需要开发者自行决定。

二、拖拽过程触发的一些事件

2.1 被拖放目标触发的事件

给被拖放目标元素绑定三个事件 dragstart、drag、dragend。

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dragDom = document.getElementById('box')
    dragDom.addEventListener('dragstart', (e) => {
        console.log('开始拖动');
    })
    dragDom.addEventListener('drag', (e) => {
        console.log('拖动中');
    })
    dragDom.addEventListener('dragend', (e) => {
        console.log('结束拖动');
    })
</script>

React

<div  
    draggable="true"
    onDragStart={(e) => {
      console.log("开始拖动", e);
    }}
    onDrag={(e) => {
      console.log("拖动中", e);
    }}
    onDragEnd={(e) => {
      console.log("结束拖动", e);
    }}
>
>draggable box</div>
<div onDragOver={(e) => {e.preventDefault()}}>放置区域</div>

开始拖动触发 dragstart ,拖动过程中(鼠标不松开)触发drag,松开鼠标(或者按下 Esc 键)触发 dragend
在这里插入图片描述

2.2 被拖拽元素在放置区域内会触发的事件

先给放置目标元素绑定四个事件

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragenter', (e) => {
        console.log('进入到了放置区域~');
    })
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
        console.log('在放置区域内拖拽中~');
    })
    dropDom.addEventListener('dragleave', (e) => {
        console.log('离开了放置区域~');
    })
    dropDom.addEventListener('drop', (e) => {
        console.log('在放置区域内,放下了被拖拽元素~')
    })
</script>

拖拽元素进入放置区域内时触发 dragenter 事件,在放置区域内移动被拖放(鼠标不松开)元素触发 dragover 事件,被拖放元素离开放置区域触发 dragleave 事件,在放置区域内松开鼠标触发 drop 事件。
在这里插入图片描述

三、实现真正意义上的元素拖放

放置被拖拽元素:

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
        console.log('在放置区域内拖拽中~');
    })
    dropDom.addEventListener('drop', (e) => {
        console.log('在放置区域内,放下了被拖拽元素~')
        e.target.appendChild(document.getElementById('box'))
    })
</script>

在这里插入图片描述
放置自定义内容

dropDom.addEventListener('drop', (e) => {
    console.log('在放置区域内,放下了被拖拽元素~')
    let customCOntent = '<p>自定义内容</p>'
    e.target.innerHTML = e.target.innerHTML + customCOntent
})

在这里插入图片描述

四、dataTransfer 对象

4.1 从被拖放元素向可放置元素传递数据

传递一个简单的字符串数据

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    let dragDom = document.getElementById('box')

    dragDom.addEventListener('dragstart', (e) => {
        e.dataTransfer.setData('text/plain', '自定义数据')
    })
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
    dropDom.addEventListener('drop', (e) => {
        let data = e.dataTransfer.getData('text/plain')
        console.log('你传递的数据为:', data);
    })
</script>

在这里插入图片描述
⚡注意:只能在 dragstart 事件中设置数据,在其他地方设置无效。且只能在 drop 事件中获取设置的数据,其他事件中获取不到。
案例:根据传递的数据放置不同的内容。

<div id="box" draggable="true">draggable box</div>
<div id="droppable">放置区域</div>
<script>
    let dropDom = document.getElementById('droppable')
    let dragDom = document.getElementById('box')
    dropDom.addEventListener('dragover', (e) => {
        e.preventDefault()
    })
    dropDom.addEventListener('drop', (e) => {
        let num = e.dataTransfer.getData('num')
        console.log(num);
        if(num > 5)
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字大于5</p>'
        else if(num == 5) 
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字等于5</p>'
        else
            e.target.innerHTML = e.target.innerHTML + '<p>传递的数字小于5</p>'
    })
    dragDom.addEventListener('dragstart', (e) => {
        let num = Math.floor(Math.random() * 10) + 1;
        e.dataTransfer.setData('num', num)
    })
</script>

在这里插入图片描述

4.2 自定义拖拽过程中跟随鼠标移动的内容

设置为一个图片:

<script>
	import Tag from "../../style/imgs/attributeTag/路径.png"; //已经存在的图片
    let dragDom = document.getElementById('box')
    dragDom.addEventListener('dragstart', (e) => {
        let img = new Image()
        // 创建一个图像并且使用它作为拖动图像
 		// 请注意: 改变 "example.gif" 为一个已经存在的图片
 		// 或者,一个还没有创建出来的图片,那么浏览器将会使用默认的拖动图片
 		// 译者注:默认的拖动图片与拖动对象没有联系。一般是一个小型文件图标
 		// 例如:
 		// mg.src = Tag 
 		//或
 		// mg.src = `data:image/png;base64,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`;
        img.src = 'example.gif'
        e.dataTransfer.setDragImage(img, 10, 10)
    })
</script>

在这里插入图片描述

4.3 设置放置前的反馈图标

在 dragover 中设置 dropEffect 的值

dropDom.addEventListener('dragover', (e) => {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'link' // none || move || copy || link
})
  • 值为 none 或者经过不可放置区域,显示禁止放置图标在这里插入图片描述
  • 值为 move 时
    在这里插入图片描述
  • 值为 copy 时
    在这里插入图片描述
  • 值为 link 时
    在这里插入图片描述

4.4 拖动文件上传

拖拽系统文件到放置区域,并打印拖拽的文件信息:

dropDom.addEventListener('drop', (e) => {
    e.preventDefault()
    // 上传的文件列表
    let fileList = e.dataTransfer.files
    for (let i = 0; i < fileList.length; i++) {
        const file = fileList[i];
        console.log('文件名:' + file.name);
        console.log('文件大小:' + file.size);
        // 后续操作 比如:调接口上传文件
    }
})

在这里插入图片描述

4.5 清除 setData() 的值

dropDom.addEventListener('drop', (e) => {
    console.log(e.dataTransfer.getData('text/plain'));
    console.log(e.dataTransfer.getData('text/html'));
})

dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', '自定义数据')
    e.dataTransfer.setData('text/html', '自定义数据2')
    e.dataTransfer.clearData('text/html')
})

在这里插入图片描述

4.6 查看设置了哪些类型的值

dropDom.addEventListener('drop', (e) => {
    console.log(e.dataTransfer.types);
})
dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.setData('text/plain', '自定义数据')
    e.dataTransfer.setData('text/html', '自定义数据2')
})

在这里插入图片描述

4.7 effectAllowed 属性取值会影响到 dropEffect 的取值效果。

effectAllowed 的取值有: + none -> 此项表示 dropEffect 设置任何值都是禁止效果 + copy -> dropEffect 可以设置为 copy + copyLink -> dropEffect 可以设置为 copy 和 link + copyMove -> dropEffect 可以设置为 copy 和 Move + link -> dropEffect 可以设置为 link + linkMove -> dropEffect 可以设置为 link 和 Move + move -> dropEffect 可以设置为 Move + all -> dropEffect 可以设置为所有合法值 + uninitialized -> 等同 all 效果

dropDom.addEventListener('dragover', (e) => {
    e.preventDefault()
    e.dataTransfer.dropEffect = 'move'
})
dragDom.addEventListener('dragstart', (e) => {
    e.dataTransfer.effectAllowed = 'none'
})

上面即使 dropEffect 设置为 move, 但是 effectAllowed 的值为 none,所有还是禁止放置的反馈图标。
在这里插入图片描述

五、总结

  • 实现一个拖拽功能时先定义好被拖拽元素和放置区域元素。
  • 所有的放置操作都是在 drop 事件中完成。
  • 放置前的反馈效果可以根据你传递的数据来设置 dropEffect 显示不同的效果。
  • 被拖拽元素也可以是放置区域,放置区域也可以是被拖拽元素,两者没有明确的界限。
  • 功能自定义按需求开发
举报

相关推荐

0 条评论