为什么即使拖放目标元素 class 列表属性不包含可拖动元素 ID 也会执行拖放?
Why drag and drop execute even if drop target element class list attributes doesn't contain draggable element id?
当且仅当所讨论的放置目标元素包含可拖动元素 ID 作为其 class 属性之一时,我希望将可拖动元素放入放置目标元素中。
因此,当将 id="chigaco" 的可拖动元素放入其 class 列表属性包含“chigaco”的放置目标元素时,代码会按预期执行。
当用户尝试将所述元素放入 class 列表属性不包含“chigaco”的放置目标元素时,不会执行放置。到目前为止一切顺利。
问题在于代码将可拖动元素放入具有 class 列表属性的放置目标元素中,其中包含可拖动元素 ID。但我希望我的代码什么也不做。
希望我说的有道理。如果不尝试使用“应用程序”,它将不言自明
const drags = document.querySelectorAll(".drag");
const empties = document.querySelectorAll(".empty");
for(const drag of drags) {
drag.addEventListener("dragstart", function(e) {
drag.classList.add("purple")
})
drag.addEventListener("dragend", function(e) {
setTimeout(() => drag.classList.remove("purple"), 0)
})
for(const empty of empties) {
empty.addEventListener("dragover", function(e) {
e.preventDefault();
console.log("dragover");
})
empty.addEventListener("dragenter", function(e) {
e.preventDefault()
console.log("dragenter")
})
empty.addEventListener("dragleave", function(e) {
console.log("leave")
console.log(empty)
})
empty.addEventListener("drop", function(e) {
if(empty.classList.contains(drag.id) === false) return
empty.append(drag)
})
}
}
.container {
display: flex;
}
.empty {
border: 1px black solid;
height: 310px;
width: 310px;
margin: 10px;
flex-direction: row;
}
.fill {
border: 1px black solid;
height: 100px;
width: 100px;
margin: 10px;
}
.drag {
border: 1px black solid;
height: 300px;
width: 300px;
margin: 10px;
margin-left: 0;
flex-direction: row;
}
.cointainer1 {
margin-left: 0;
}
.parent {
display: flex;
flex-direction: row;
}
.purple {
background-color: purple;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<title></title>
</head>
<body>
<div class="parent">
<div class="container1">
<div id="chigaco" class="drag chigaco" draggable="true">bulls</div>
<div id="losAngeles" class="drag losAngeles" draggable="true">laker</div>
<div id="boston" class="drag boston" draggable="true">celtics</div>
<div id="spurs" class="drag spurs" draggable="true">san Antionio</div>
<div id="knicks" class="drag knicks" draggable="true">New York</div>
</div>
<div class="container2">
<div class="empty chigaco">chigaco</div>
<div class="empty losAngeles">losAngeles</div>
<div class="empty boston">boston</div>
<div class="empty spurs">spurs</div>
<div class="empty knicks">knicks</div>
</div>
</div>
</body>
<script src="index.js" type="text/javascript">
</script>
</html>
方法很好,但这里有两个主要错误:
- 嵌套的侦听器。每个
drag
向所有 empty
添加一个监听器,这些需要是两个单独的循环,否则你正在乘以监听器(拖动*空)
- 不存储拖动的元素,因为需要比较id和class
修复方法如下(参见 JS 代码中的注释)
const drags = document.querySelectorAll(".drag");
const empties = document.querySelectorAll(".empty");
// dragged Element
let currentDrag = null;
// Loop for drags
for(const drag of drags) {
drag.addEventListener("dragstart", function(e) {
drag.classList.add("purple");
currentDrag = e.target; // Store the dragged element
});
drag.addEventListener("dragend", function(e) {
setTimeout(() => {
drag.classList.remove("purple");
currentDrag = null; // Remove the dragged element, not required but consistent in logic
}, 10);
});
}
// Loop for empties
for(const empty of empties) {
empty.addEventListener("dragover", function(e) {
e.preventDefault();
});
empty.addEventListener("drop", function(e, i) {
const dropElement = e.target; // Declaring for clarity
if(!currentDrag || dropElement.classList.contains(currentDrag.id) === false) return
empty.append(currentDrag);
})
}
.container {
display: flex;
}
.empty {
border: 1px black solid;
height: 310px;
width: 310px;
margin: 10px;
flex-direction: row;
}
.fill {
border: 1px black solid;
height: 100px;
width: 100px;
margin: 10px;
}
.drag {
border: 1px black solid;
height: 300px;
width: 300px;
margin: 10px;
margin-left: 0;
flex-direction: row;
}
.cointainer1 {
margin-left: 0;
}
.parent {
display: flex;
flex-direction: row;
}
.purple {
background-color: purple;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<title></title>
</head>
<body>
<div class="parent">
<div class="container1">
<div id="chigaco" class="drag chigaco" draggable="true">bulls</div>
<div id="losAngeles" class="drag losAngeles" draggable="true">laker</div>
<div id="boston" class="drag boston" draggable="true">celtics</div>
<div id="spurs" class="drag spurs" draggable="true">san Antionio</div>
<div id="knicks" class="drag knicks" draggable="true">New York</div>
</div>
<div class="container2">
<div class="empty chigaco">chigaco</div>
<div class="empty losAngeles">losAngeles</div>
<div class="empty boston">boston</div>
<div class="empty spurs">spurs</div>
<div class="empty knicks">knicks</div>
</div>
</div>
</body>
</html>
当且仅当所讨论的放置目标元素包含可拖动元素 ID 作为其 class 属性之一时,我希望将可拖动元素放入放置目标元素中。
因此,当将 id="chigaco" 的可拖动元素放入其 class 列表属性包含“chigaco”的放置目标元素时,代码会按预期执行。
当用户尝试将所述元素放入 class 列表属性不包含“chigaco”的放置目标元素时,不会执行放置。到目前为止一切顺利。
问题在于代码将可拖动元素放入具有 class 列表属性的放置目标元素中,其中包含可拖动元素 ID。但我希望我的代码什么也不做。
希望我说的有道理。如果不尝试使用“应用程序”,它将不言自明
const drags = document.querySelectorAll(".drag");
const empties = document.querySelectorAll(".empty");
for(const drag of drags) {
drag.addEventListener("dragstart", function(e) {
drag.classList.add("purple")
})
drag.addEventListener("dragend", function(e) {
setTimeout(() => drag.classList.remove("purple"), 0)
})
for(const empty of empties) {
empty.addEventListener("dragover", function(e) {
e.preventDefault();
console.log("dragover");
})
empty.addEventListener("dragenter", function(e) {
e.preventDefault()
console.log("dragenter")
})
empty.addEventListener("dragleave", function(e) {
console.log("leave")
console.log(empty)
})
empty.addEventListener("drop", function(e) {
if(empty.classList.contains(drag.id) === false) return
empty.append(drag)
})
}
}
.container {
display: flex;
}
.empty {
border: 1px black solid;
height: 310px;
width: 310px;
margin: 10px;
flex-direction: row;
}
.fill {
border: 1px black solid;
height: 100px;
width: 100px;
margin: 10px;
}
.drag {
border: 1px black solid;
height: 300px;
width: 300px;
margin: 10px;
margin-left: 0;
flex-direction: row;
}
.cointainer1 {
margin-left: 0;
}
.parent {
display: flex;
flex-direction: row;
}
.purple {
background-color: purple;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="index.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<title></title>
</head>
<body>
<div class="parent">
<div class="container1">
<div id="chigaco" class="drag chigaco" draggable="true">bulls</div>
<div id="losAngeles" class="drag losAngeles" draggable="true">laker</div>
<div id="boston" class="drag boston" draggable="true">celtics</div>
<div id="spurs" class="drag spurs" draggable="true">san Antionio</div>
<div id="knicks" class="drag knicks" draggable="true">New York</div>
</div>
<div class="container2">
<div class="empty chigaco">chigaco</div>
<div class="empty losAngeles">losAngeles</div>
<div class="empty boston">boston</div>
<div class="empty spurs">spurs</div>
<div class="empty knicks">knicks</div>
</div>
</div>
</body>
<script src="index.js" type="text/javascript">
</script>
</html>
方法很好,但这里有两个主要错误:
- 嵌套的侦听器。每个
drag
向所有empty
添加一个监听器,这些需要是两个单独的循环,否则你正在乘以监听器(拖动*空) - 不存储拖动的元素,因为需要比较id和class
修复方法如下(参见 JS 代码中的注释)
const drags = document.querySelectorAll(".drag");
const empties = document.querySelectorAll(".empty");
// dragged Element
let currentDrag = null;
// Loop for drags
for(const drag of drags) {
drag.addEventListener("dragstart", function(e) {
drag.classList.add("purple");
currentDrag = e.target; // Store the dragged element
});
drag.addEventListener("dragend", function(e) {
setTimeout(() => {
drag.classList.remove("purple");
currentDrag = null; // Remove the dragged element, not required but consistent in logic
}, 10);
});
}
// Loop for empties
for(const empty of empties) {
empty.addEventListener("dragover", function(e) {
e.preventDefault();
});
empty.addEventListener("drop", function(e, i) {
const dropElement = e.target; // Declaring for clarity
if(!currentDrag || dropElement.classList.contains(currentDrag.id) === false) return
empty.append(currentDrag);
})
}
.container {
display: flex;
}
.empty {
border: 1px black solid;
height: 310px;
width: 310px;
margin: 10px;
flex-direction: row;
}
.fill {
border: 1px black solid;
height: 100px;
width: 100px;
margin: 10px;
}
.drag {
border: 1px black solid;
height: 300px;
width: 300px;
margin: 10px;
margin-left: 0;
flex-direction: row;
}
.cointainer1 {
margin-left: 0;
}
.parent {
display: flex;
flex-direction: row;
}
.purple {
background-color: purple;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
<title></title>
</head>
<body>
<div class="parent">
<div class="container1">
<div id="chigaco" class="drag chigaco" draggable="true">bulls</div>
<div id="losAngeles" class="drag losAngeles" draggable="true">laker</div>
<div id="boston" class="drag boston" draggable="true">celtics</div>
<div id="spurs" class="drag spurs" draggable="true">san Antionio</div>
<div id="knicks" class="drag knicks" draggable="true">New York</div>
</div>
<div class="container2">
<div class="empty chigaco">chigaco</div>
<div class="empty losAngeles">losAngeles</div>
<div class="empty boston">boston</div>
<div class="empty spurs">spurs</div>
<div class="empty knicks">knicks</div>
</div>
</div>
</body>
</html>