我正在开发一种带有 HTML5 拖放 API 的益智游戏。我构建了一个 3 行的网格,每行 4 列,给出了 12 个正方形。除一个方 block 外,所有方 block 都包含从 1 到 11 的数字。空方 block 是放置区,即可以将任何方 block 拖入其中。
当元素被拖动时,dataTransfer.setData被设置为被拖动元素的id,而ondrop事件使用dataTransfer.getData()获取数据,其结果用于查询被拖动元素的dom,然后克隆后,dropzone 现在被克隆的节点替换。拖动元素的来源也被替换为拖放区。
var squares = document.querySelectorAll(".item");
var dropzone = document.querySelector(".col-lg-3.dropzone");
function startDrag(e){
e.dataTransfer.setData("text", e.target.id);
console.log(e.target)
}
function overDrag(e){
e.preventDefault();
e.target.classList.toggle("dropzone-active");
}
function leaveDrag(e){
e.preventDefault();
e.target.classList.toggle("dropzone-active");
}
function dropItem(e){
e.preventDefault();
var data = e.dataTransfer.getData("text");
var draggedElem = document.getElementById(data)
var clone = draggedElem.cloneNode(true);
var emptyzone = dropzone.cloneNode(false);
emptyzone.className = "col-lg-3 dropzone";
draggedElem.parentNode.replaceChild(emptyzone,draggedElem);
clone.id = data;
e.target.parentNode.replaceChild(clone, e.target);
}
for(var i=0; i<squares.length; i++){
squares[i].addEventListener("dragstart", startDrag, false);
}
dropzone.addEventListener("dragover", overDrag, false);
dropzone.addEventListener("dragleave", leaveDrag, false);
dropzone.addEventListener("drop", dropItem, false);
#gameZone{
width:800px;
height:500px;
background-color: rgba(0,0,0,.5);
margin: 0 auto;
padding:15px;
position:relative;
}
.item,
.dropzone{
background-color:red;
margin-right:10px;
margin-bottom:15px;
width:100px;
height:100px;
font-size: 2em;
color:#fff;
text-align:center;
}
.drag-active{
position:absolute;
z-index: 10;
}
.dropzone-active{
border:dashed 3px white;
}
.dropzone{
background-color:rgba(255,255,255,.6);
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<section id="gameZone">
<div class="row">
<div class="col-lg-3 item" id="one" draggable="true">1</div>
<div class="col-lg-3 item" id="three" draggable="true">3</div>
<div class="col-lg-3 item" id="two" draggable="true">2</div>
<div class="col-lg-3 item" id="four" draggable="true">4</div>
</div>
<div class="row">
<div class="col-lg-3 dropzone"></div>
<div class="col-lg-3 item" id="five" draggable="true">5</div>
<div class="col-lg-3 item" id="six" draggable="true">6</div>
<div class="col-lg-3 item" id="nine" draggable="true">9</div>
</div>
<div class="row">
<div class="col-lg-3 item" id="seven" draggable="true">7</div>
<div class="col-lg-3 item" id="eight" draggable="true">8</div>
<div class="col-lg-3 item"id="eleven" draggable="true">11</div>
<div class="col-lg-3 item" id="ten" draggable="true">10</div>
</div>
</section>
现在的问题是,第一个拖放操作成功,但是,尝试在新的放置区中拖动新元素不起作用,它只是无法识别 ondragenter、ondragleave、ondragover 和 drop 事件不再了。
最佳答案
您可以创建一个函数来设置 dropzone
变量,将 dragover
、dragleave
、drop
事件附加到当前dropzone
元素。在 drop
事件监听器中调用传递 data
的函数,将 dragstart
事件附加到当前具有 id
data< 的元素
.
var squares = document.querySelectorAll(".item");
var dropzone;
//= document.querySelector(".col-lg-3.dropzone");
function startDrag(e) {
e.dataTransfer.setData("text", e.target.id);
}
function overDrag(e) {
e.preventDefault();
e.target.classList.toggle("dropzone-active");
}
function leaveDrag(e) {
e.preventDefault();
e.target.classList.toggle("dropzone-active");
}
function dropItem(e) {
e.preventDefault();
var data = e.dataTransfer.getData("text");
var draggedElem = document.getElementById(data)
var clone = draggedElem.cloneNode(true);
var emptyzone = dropzone.cloneNode(false);
emptyzone.className = "col-lg-3 dropzone";
draggedElem.parentNode.replaceChild(emptyzone, draggedElem);
clone.id = data;
e.target.parentNode.replaceChild(clone, e.target);
setResetDND(data);
}
for (var i = 0; i < squares.length; i++) {
squares[i].addEventListener("dragstart", startDrag, false);
}
function setResetDND(id) {
dropzone = document.querySelector(".col-lg-3.dropzone");
dropzone.addEventListener("dragover", overDrag, false);
dropzone.addEventListener("dragleave", leaveDrag, false);
dropzone.addEventListener("drop", dropItem, false);
if (id) {
document.getElementById(id)
.addEventListener("dragstart", startDrag)
}
}
setResetDND();
#gameZone {
width: 800px;
height: 500px;
background-color: rgba(0, 0, 0, .5);
margin: 0 auto;
padding: 15px;
position: relative;
}
.item,
.dropzone {
background-color: red;
margin-right: 10px;
margin-bottom: 15px;
width: 100px;
height: 100px;
font-size: 2em;
color: #fff;
text-align: center;
}
.drag-active {
position: absolute;
z-index: 10;
}
.dropzone-active {
border: dashed 3px white;
}
.dropzone {
background-color: rgba(255, 255, 255, .6);
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<section id="gameZone">
<div class="row">
<div class="col-lg-3 item" id="one" draggable="true">1</div>
<div class="col-lg-3 item" id="three" draggable="true">3</div>
<div class="col-lg-3 item" id="two" draggable="true">2</div>
<div class="col-lg-3 item" id="four" draggable="true">4</div>
</div>
<div class="row">
<div class="col-lg-3 dropzone"></div>
<div class="col-lg-3 item" id="five" draggable="true">5</div>
<div class="col-lg-3 item" id="six" draggable="true">6</div>
<div class="col-lg-3 item" id="nine" draggable="true">9</div>
</div>
<div class="row">
<div class="col-lg-3 item" id="seven" draggable="true">7</div>
<div class="col-lg-3 item" id="eight" draggable="true">8</div>
<div class="col-lg-3 item" id="eleven" draggable="true">11</div>
<div class="col-lg-3 item" id="ten" draggable="true">10</div>
</div>
</section>
关于javascript - 拖动事件仅触发一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41411266/