HTML5原生的Drag和Drop,H5原生拖放(Drag and Drop)demo以及浏览器兼容性处理

H5原生拖放(Drag and Drop)demo以及浏览器兼容性处理

这篇文章发布于 2020/08/22,归类于 JavaScript

标签:

js拖拽,原生js拖放,js拖放,js拖放浏览器兼容性,HTML5 拖放,dragstart,drop

一般在网页中,如果需要实现拖放,首先要有两个元素

可拖动的元素,元素draggable="true"属性就是可拖放,如果设置为false就是不可拖放

可以放置的区域,注意chrome如果不将放置区域的onenter和onover事件阻止默认行为,无法触发drop函数

e85284e8b226f37743cc29c6e75cddf6.png

拖放的过程中的钩子

拖动元素时,会触发元素的 dragstart 钩子函数,在函数里可以设置数据、以及拖动到放置区域的鼠标样式

当拖动元素进入放置区域时,放置区域元素会触发一次dragenter钩子(拖动进入),触发多次dragover(拖动元素在放置区域移动中),放下时再触发放置元素的drop钩子,这里可以用来接收拖拽元素dragstart设置的data,处理拖动的行为

注意事项:浏览器兼容性处理

在Chrome中,放置区域的ondrop事件不触发,需要在onenter和onover事件里阻止默认行为(火狐不需要这样处理)

event.dataTransfer.effectAllowed只能设置鼠标样式,不能设置拖动元素行为,drag后之前的元素会消失,想要保留需要使用cloneNode来操作

// 放置后,删除原来的图片

// ev.target.appendChild(document.querySelector(`#${reciveData}`))

// 放置后,保留原图片

ev.target.appendChild(document.querySelector(`#${reciveData}`).cloneNode(true))

在Firefox(火狐)浏览器里drop图片后,会新在新的tab也打开图片,不仅要在drop里阻止默认行为,还要阻止事件冒泡

demo实例

demo如下,demo 在线体验地址,demo github源码

f7a219cefc66c9783b55effa840fc315.png

test.png

// 被拖动元素的事件监听

let img = document.getElementById('img')

// 当元素开始拖动时触发,仅触发一次

img.addEventListener('dragstart', (ev) => {

// 设置值,在放置区域触发drop事件时,可以通过ev.dataTransfer.getData获取这里的值

ev.dataTransfer.setData("text", ev.target.id)

// link 会影响拖动到放置区域的鼠标样式,只是样式,并不决定行为

ev.dataTransfer.effectAllowed = 'copy';

})

// 放置区域A的事件监听

let targetA = document.getElementById('targetA')

// 当有拖动元素(放到)落到放置区域时触发,一次

targetA.addEventListener('drop', (ev) => {

ev.stopPropagation(); // 必要,阻止冒泡,防止火狐浏览器放置图片后打开新的窗口

ev.preventDefault(); // 必要,阻止默认行为 防止火狐浏览器放置后直接打开图片

// 放置落下时,接收被拖拽的元素在 dragstart时用ev.dataTransfer.setData设置的值

// 这里传的id备用

let reciveData = ev.dataTransfer.getData("text")

console.log('drop, recive data', reciveData, ev.dataTransfer.dropEffect)

// 必要,设置拖动后放置的效果,移动还是copy

// 放置后,删除原来的图片

// ev.target.appendChild(document.querySelector(`#${reciveData}`))

// 放置后,保留原图片

ev.target.appendChild(document.querySelector(`#${reciveData}`).cloneNode(true))

ev.target.classList.remove('active') // 必要,放置在区域里后,还原样式

})

// 当拖动元素移动到放置区域时触发,触发多次

targetA.addEventListener('dragover', (ev) => {

ev.preventDefault() // 必要,chrome drop兼容必须

})

// 当拖动元素进入放置区域时触发,一次

targetA.addEventListener('dragenter', (ev) => {

ev.preventDefault() // 必要,chrome drop兼容必须

ev.target.classList.add('active') // 必要,设置进入时的样式

})

// 当拖动元素离开放置区域时触发,一次

targetA.addEventListener('dragleave', (ev) => {

ev.target.classList.remove('active') // 必要,设置离开后的样式

})

参考资料文档

扩展:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值