基本效果展示:
基本思路:
使元素可以被拖拽(利用 draggable 属性, 注意:链接和图片默认是可拖拽的)
拖拽时,通过被拖拽节点和其他节点的drag事件交互,来切换两个节点的位置(非唯一方法)
添加用户拖拽交互效果
用到的方法:
ondrag 事件在元素或者选取的文本被拖动时触发。
在拖动目标上触发(源目标元素):
ondragstart – 用户开始拖动元素
ondrag – 元素正在被拖动
ondragend – 用户结束元素拖动
释放目标时触发的事件:
ondragenter – 当被拖动的对象进入其容器范围内时触发
ondragover – 当被拖动的对象在另一对象容器范围内拖动时触发
ondragleave – 当被拖动的对象离开其容器范围内时触发
ondrop – 在一个拖动过程中,释放鼠标键时触发
注意: 在拖动元素时,每隔 350 毫秒会触发 ondrag 事件。
基本实现(无交互):
function dragHandler() {
// 用来存取被拖拽的节点
let draggedNode = null
// 获取可拖拽节点
const dragNodes = document.querySelectorAll('div[draggable="true"]')
// 给可拖拽节点绑定相关事件
dragNodes.forEach(item => {
item.ondragstart = () => {
draggedNode = item
}
// 默认情况下,数据/元素不能在其他元素中被拖放,也就是会阻止你做drop操作,所以取消其默认行为
item.ondragover = e => {
e.preventDefault()
}
// 被拖拽的节点,被释放后进行节点替换
item.ondrop = e => {
if (draggedNode !== null && draggedNode !== item) {
const temp = document.createElement('div')
const dragBox = document.getElementById('drag-box')
dragBox.replaceChild(temp, e.target)
dragBox.replaceChild(e.target, draggedNode)
dragBox.replaceChild(draggedNode, temp)
}
}
})
}
dragHandler()
有交互效果:
function dragHandler() {
// 用来存取被拖拽的节点
let draggedNode = null
// 存放被拖拽节点的背景
let draggedNodeBg = null
// 存放被拖拽节点进入的容器(节点) 的旧背景
let dragEnterNodeBg = null
// 获取可拖拽节点
const dragNodes = document.querySelectorAll('div[draggable="true"]')
// 给可拖拽节点绑定事件
dragNodes.forEach(item => {
item.ondragstart = () => {
draggedNode = item
// 拖拽开始,设置背景
draggedNodeBg = getComputedStyle(item).background
item.style.background = '#bbb'
}
// 默认情况下,数据/元素不能在其他元素中被拖放,也就是会阻止你做drop操作,所以取消其默认行为
item.ondragover = e => {
e.preventDefault()
}
// 被拖拽的节点,被释放后进行节点替换
item.ondrop = e => {
if (dragEnterNodeBg) {
// 拖拽被释放,恢复目标节点背景
e.target.style.background = dragEnterNodeBg
}
if (draggedNode !== null && draggedNode !== item) {
const temp = document.createElement('div')
const dragBox = document.getElementById('drag-box')
dragBox.replaceChild(temp, e.target)
dragBox.replaceChild(e.target, draggedNode)
dragBox.replaceChild(draggedNode, temp)
}
}
// 样式交互
item.ondragend = () => {
item.style.background = draggedNodeBg
}
item.ondragenter = () => {
if (item !== draggedNode) {
dragEnterNodeBg = getComputedStyle(item).background
item.style.background = 'darkcyan'
}
}
item.ondragleave = () => {
if (dragEnterNodeBg && item !== draggedNode) {
item.style.background = dragEnterNodeBg
}
}
})
}
dragHandler()