拖动事件仅触发一次

时间:2016-12-31 19:46:42

标签: javascript html5 drag-and-drop

我正在研究一种带有HTML5拖放api的益智游戏。我构建了一个3行的网格,每行4个col,给我12个方块。除了一个正方形之外的所有正方形都包含一些从1到11的数字。空的正方形意味着掉落区域,即可以拖入任何正方形。

当拖动元素时,dataTransfer.setData被设置为被拖动元素的id,而ondrop事件使用dataTransfer.getData()的结果获取数据,其结果用于查询被拖动元素的dom,然后克隆后,dropzone现在被克隆节点替换。拖动元素即将来源也将被替换为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);
&#13;
	#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);
	}
&#13;
<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>
&#13;
&#13;
&#13;

现在的问题是第一次拖放操作是成功的,但是,尝试在新的dropzone中拖动新元素并不起作用,它只是不识别ondragenter,ondragleave,ondragover和丢弃事件了。

1 个答案:

答案 0 :(得分:1)

您可以创建一个函数来设置dropzone变量,将dragoverdragleavedrop事件附加到当前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>