简述:JavaScript的拖拽api相必大家都不陌生,今天来分享下元素在拖动时触发的事件,顺便做下记录。
一、ondragstart事件
ondragstart事件在拖动元素时触发,通常用于设置拖动时的数据类型和数据。可以通过event.dataTransfer.setData()方法设置数据类型和数据。
示例代码:
// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>
// JS
var drag = document.getElementById("drag");
// 拖拽开始 执行一次
drag.addEventListener("dragstart", function(event) {
event.dataTransfer.setData("text/plain", "这是拖动的数据");
});
二、ondragover事件
ondragover事件在拖动元素在目标元素上方时触发,通常用于防止默认的拖放行为。可以通过event.preventDefault()方法阻止默认行为。
示例代码:
// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>
// JS
var drop = document.getElementById("drop");
// 拖拽经过 一直执行(类似Mousemove事件)
drop.addEventListener("dragover", function(event) {
event.preventDefault();
});
三、ondragenter事件
ondragenter事件在拖动元素进入目标元素时触发,通常用于设置拖动时的样式。
示例代码:
// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>
// CSS
#drop {
border: 2px dashed #ccc;
}
#drop.dragover {
border-color: #f00;
}
// JS
var drop = document.getElementById("drop");
// 拖拽进入 执行一次
drop.addEventListener("dragenter", function(event) {
drop.classList.add("dragover");
});
drop.addEventListener("dragleave", function(event) {
drop.classList.remove("dragover");
});
四、ondrop事件
ondrop事件在拖动元素放置在目标元素上时触发,通常用于获取拖动时设置的数据。
示例代码:
// HTML
<div id="drag" draggable="true">拖动我</div>
<div id="drop">放置区域</div>
// JS
var drop = document.getElementById("drop");
// 拖拽放手 执行一次,table中的tr td默认禁止拖拽在上面
drop.addEventListener("drop", function(event) {
var data = event.dataTransfer.getData("text/plain");
console.log(data);
});
下面通过一个课程表小案例,来实际应用一下,使用JavaScript拖拽API实现的课程表案例,效果如下:
HTMl:
<div class="demo_box">
<div class="left" data-drop="move">
<div data-effect="copy" draggable="true" class="subjects color1">语文</div>
<div data-effect="copy" draggable="true" class="subjects color2">数学</div>
</div>
<table class="right_table" border="1">
<thead>
<tr>
<td>星期一</td>
<td>星期二</td>
<td>星期三</td>
</tr>
</thead>
<tbody>
<tr>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
</tbody>
</table>
</div>
<script src="./draw.js"></script>
// 用到的自定义属性
// draggable="true"
// data-effect="copy"
// data-drop="copy"
// data-drop="move"
JavaScript:
// 事件委托 获取父元素
const containerBox = document.querySelector('.demo_box');
// console.log(containerBox);
let source;//定义source ,用于拿到节点‘
// 拖拽开始 执行一次
containerBox.ondragstart = (e) => {
// console.log("start", e.target);
// 拖拽事件改为移动 此事拖拽时元素上没有加号
// e.dataTransfer.effectAllowed = "move";
// 默认是copy复制 此事拖拽时元素上有加号
// e.dataTransfer.effectAllowed = "copy";
// 自定义事件data-effect = "copy" ,此事件可共享, 所以
e.dataTransfer.effectAllowed = e.target.dataset.effect;
// 拿到节点
source = e.target;
};
// 拖拽经过 一直执行,类似Mousemove事件
containerBox.ondragover = (e) => {
// console.log("over", e.target);
// 阻止默认行为 这里就是开启表格的drop事件
e.preventDefault();
};
function claerStyle() {
// 清除之前的背景颜色over_bg
document.querySelectorAll(".over_bg").forEach((node) => {
node.classList.remove("over_bg");
});
}
// 判断父元素
function getDropNode(node) {
while (node) {
if (node.dataset && node.dataset.drop) {
return node;
}
node = node.parentNode;
}
}
// 拖拽进入 执行一次
containerBox.ondragenter = (e) => {
// 清除之前的背景调用
claerStyle();
// console.log("enter", e.target);
// 改变背景颜色 添加over_bg时父子都会触发
// e.target.classList.add('over_bg');
// 所以给right里的td添加data-drop="copy"只接受复制
// 给left添加data-drop="move"
// const dropNode = e.target;
// 判断父元素
const dropNode = getDropNode(e.target);
if (dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed) {
//如果相等 表示该节点能够接受目前拖拽的节点
dropNode.classList.add('over_bg');
}
};
// 拖拽放手 执行一次,table中的tr td默认禁止拖拽在上面,所以需要阻止默认行为;
containerBox.ondrop = (e) => {
// console.log("drop", e.target);
// 首先清除之前的背景颜色
claerStyle();
const dropNode = getDropNode(e.target);
if (dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed) {
//如果相等 表示该节点能够接受目前拖拽的节点
// 分为两种情况
if (dropNode.dataset.drop === "copy") {
dropNode.innerHTML = '';
// 克隆元素 source是上面拿到的元素
const cloned = source.cloneNode(true);
cloned.dataset.effect = "move";
// 添加克隆的元素
dropNode.appendChild(cloned);
}
else {
source.remove();
}
}
};
视频讲解:
使用方式:拖拽API,课程表小案例讲解(复制后,打开抖音搜索)
1.02 lPX:/ 拖拽API # 前端开发工程师 # JavaScript # 编程 # 程序员 # web前端 # 前端 # 前端开发 https://v.douyin.com/UuyyMjc/