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函数

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

拖放的过程中的钩子

拖动元素时,会触发元素的 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源码

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

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

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') // 必要,设置离开后的样式

})

参考资料文档

扩展:

你可能感兴趣的:(HTML5原生的Drag和Drop,H5原生拖放(Drag and Drop)demo以及浏览器兼容性处理)