Reputation: 871
I'm working on a kind of puzzle game with HTML5 drag and drop api. I build a grid of 3 rows with 4 col per row giving me twelve squares. All but one of the squares contains some numbers from 1 to 11. The empty square is meant to be the dropzone i.e where any square can be dragged into.
When an element is dragged the dataTransfer.setData is set to the id of the element being dragged while ondrop event gets the data using dataTransfer.getData() result of which is used to query the dom for the element being dragged, then cloned after which the dropzone is now replaced with the cloned node. The source from which the dragged element is coming is also replaced with a 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>
The problem now is that the first drag and drop action is successful, however, trying to drag a new element in the new dropzone doesn't work, it just doesn't recognize the ondragenter, ondragleave, ondragover and the drop events anymore.
Upvotes: 1
Views: 2440
Reputation: 1
You can create a function to set dropzone
variable, attach dragover
, dragleave
, drop
events to current dropzone
element. Within drop
event listener call function passing data
to attach dragstart
event to element currently having 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>
Upvotes: 1