文章目录
前言
拖拽api在我们前端里面是非常常见的api
拖放(Drag 和 Drop)是很常见的特性。它指的是您抓取某物并拖入不同的位置。
这篇文章主要是通过一个案例来帮助大家来认识它的使用方法。
一、拖拽的相关事件
1.ondragstart
当拖拽开始时触发一次
2.ondragover
当拖拽到莫个元素之上时触发,会一直触发
3.ondragenter
当拖拽到莫个元素之上时触发,只会触发一次
4.ondrop
当结束拖拽时触发
二、课程表案例
1.页面准备
首先就是先准备我们的页面
2.实现元素的可拖拽
只需要在需要拖拽的元素上面写上draggable="true"元素就处于可拖拽的状态。
<li draggable="true" class="colorRed item">前端开发</li>
<li draggable="true" class="colorBlue item">思想道德</li>
<li draggable="true" class="ColorGreen item">软件工程</li>
3.功能的实现
1.阻止默认事件
这时我们发现我们移动到div,table,td这些元素上时,浏览器默认阻止我们。
这时我们使用preventDefault()方法来阻止默认事件
// 拖拽事件,当拖拽到莫个元素之上时触发,会一直触发
container.ondragover=(e)=>{
// 由于默认是不能托到表格上面的,阻止默认行为
e.preventDefault()
}
2.添加事件并修改鼠标状态为复制
这里我们可以使用自定义事件来实现标记该元素可以拖拽
// 拖拽事件,当拖拽开始时触发一次
container.ondragstart=(e)=>{
// 修改状态鼠标状态为复制
e.dataTransfer.effectAllowed = e.target.dataset.state
}
3.实现拖拽到某个元素背景变色
给每一个td元素加上自定义属性,这样可以区别于是否可以拖拽到该元素内部。
// 拖拽到某个元素上清除前面所以加的元素
function clearOverList(){
document.querySelectorAll(".over").forEach((node)=>{
node.classList.remove('over')
})
}
// 获得最外层元素节点
function getNode(node){
while(node){
if(node.dataset.drop){
return node
}
//获得父节点
node = node.parentNode
}
}
// 拖拽事件,当拖拽到莫个元素之上时触发,只会触发一次
container.ondragenter=(e)=>{
clearOverList()
const dropNode = getNode(e.target)
// 判断是否能够变色
if( dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed){
e.target.classList.add('over')
}
}
4.实现最终功能
// 拖拽事件,当结束拖拽的时候会触发一个元素
container.ondrop = (e)=>{
//清除样式
clearOverList()
const dropNode = getNode(e.target)
if( dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed){
if(dropNode.dataset.drop === 'copy'){
dropNode.innerHTML = ''
console.log(souce)
// 深度复制
const cloned = souce.cloneNode(true)
dropNode.appendChild(cloned)
}
}
}
三.全部代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>课程表</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
#head {
font-size: 26px;
background-color: #5645bf;
color: white;
}
.headerDate {
background-color: #dcdcdc;
}
.colorYellow {
background-color: yellow;
}
.colorBlue {
background-color: #7ac5cd;
}
.colorRed {
background-color: #cd5c5c;
}
.ColorGreen {
background-color: #66cdaa;
}
.tongshi {
background-color: #a15dd0;
}
table {
border: 1px solid;
}
.box{
margin: 20px auto;
}
.contLis{
width: 100px;
height: 680px;
background-color: #dcdcdc;
margin: 20px auto;
}
.item{
width: 80px;
text-align: center;
line-height: 50px;
height: 50px;
list-style: none;
margin: 10px auto;
}
table td{
width: 80px;
}
.container{
display: flex;
}
.over{
background-color: #bebebe;
}
</style>
</head>
<body>
<div class="container">
<div class="contLis" data-drop="more">
<ul>
<li data-state="copy" draggable="true" class="colorRed item">前端开发</li>
<li data-state="copy" draggable="true" class="colorBlue item">思想道德</li>
<li data-state="copy" draggable="true" class="ColorGreen item">软件工程</li>
</ul>
</div>
<table class="box" width="400px" height="680px">
<thead>
<tr class="headerDate">
<th>10月</th>
<th><div class="item">周一</div></th>
<th><div class="item">周二</div></th>
<th><div class="item">周三</div></th>
<th><div class="item">周四</div></th>
<th><div class="item">周五</div></th>
<th><div class="item">周六</div></th>
<th><div class="item">周七</div></th>
</tr>
</thead>
<tbody>
<tr>
<th class="colorYellow">1</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">2</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">3</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">4</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">5</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">6</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
<tr>
<th class="colorYellow">7</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy">
</td>
</tr>
<tr>
<th class="colorYellow">8</th>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
<td data-drop="copy"></td>
</tr>
</tbody>
</table>
</div>
<script>
// 清除函数
function clearOverList(){
document.querySelectorAll(".over").forEach((node)=>{
node.classList.remove('over')
})
}
// 获得node节点
function getNode(node){
while(node){
if(node.dataset.drop){
return node
}
node = node.parentNode
}
}
let souce = null;
const container = document.querySelector('.container')
// 拖拽事件,当拖拽开始时触发一次
container.ondragstart=(e)=>{
// 修改状态鼠标状态为复制
e.dataTransfer.effectAllowed = e.target.dataset.state
souce = e.target
console.log(souce)
}
// 拖拽事件,当拖拽到莫个元素之上时触发,会一直触发
container.ondragover=(e)=>{
// 由于默认是不能托到表格上面的阻止默认行为
e.preventDefault()
// console.log(e.target)
}
// 拖拽事件,当拖拽到莫个元素之上时触发,只会触发一次
container.ondragenter=(e)=>{
clearOverList()
const dropNode = getNode(e.target)
// 判断是否能够变色
if( dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed){
e.target.classList.add('over')
}
}
// 拖拽事件,当结束拖拽的时候会触发一个元素
container.ondrop = (e)=>{
clearOverList()
const dropNode = getNode(e.target)
if( dropNode && dropNode.dataset.drop === e.dataTransfer.effectAllowed){
if(dropNode.dataset.drop === 'copy'){
dropNode.innerHTML = ''
console.log(souce)
// 深度复制
const cloned = souce.cloneNode(true)
dropNode.appendChild(cloned)
}
}
}
</script>
</body>
</html>
总结
以上就是今天要讲的内容,本文仅仅简单介绍了拖拽式api的使用,我们通过编写了一个简单的案例来掌握了基本的使用方法。