拖放 API 实施的错误
Bug with Drag and Drop API implementation
在这些天里,我一直在尝试学习如何实现拖放 API,但我 运行 遇到了一个我无法修复的错误。实际上,如果我通过拖动交换第一个和第二个框,当我 select 和 header 并将其拖动到第二个框时,就会发生错误!这只是个案,但还有更多。我想看看调试会发生什么,但我错过了一些东西。下面是错误和代码的屏幕截图:
bug
let dragSrcEl = null;
function handleDragStart(e) {
this.classList.add('dnd__element--dragStart');
console.log(this);
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDragEnter(e) {
this.classList.add('dnd__element--dragOver');
}
function handleDragLeave(e) {
this.classList.remove('dnd__element--dragOver');
}
function handleDragEnd(e) {
this.classList.remove('dnd__element--dragStart');
items.forEach(function(item) {
item.classList.remove('dnd__element--dragOver');
});
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
if (dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
const items = document.querySelectorAll('.dnd__element');
items.forEach(function(item) {
item.classList.remove(
'dnd__element--dragStart',
'dnd__element--dragEnd',
'dnd__element--dragOver'
);
item.addEventListener('dragstart', handleDragStart, false);
item.addEventListener('dragover', handleDragOver, false);
item.addEventListener('dragenter', handleDragEnter, false);
item.addEventListener('dragleave', handleDragLeave, false);
item.addEventListener('drop', handleDrop, false);
item.addEventListener('dragend', handleDragEnd, false);
});
.dnd__element {
cursor: move;
border: 3px solid #777;
background-color: #ddd;
padding: 1rem;
border-radius: 0.5rem;
float: left;
}
.dnd__element--dragStart {
opacity: 0.4;
}
.dnd__element--dragEnd {
opacity: 1;
}
.dnd__element--dragOver {
border: 3px dotted #666;
}
.dnd__drag-zone {
height: 20rem;
background-color: cornsilk;
}
.heading-tertiary {
display: block;
background-color: darkkhaki;
padding: 2rem 1rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<section class="section-dnd">
<div class="dnd__drag-zone">
<h3 class="heading-tertiary">Drag zone</h3>
<div class="dnd__element dnd__element--dragStart" id="d1" draggable="true">
Box 1
</div>
<div class="dnd__element dnd__element--dragEnd" id="d2" draggable="true">
Box 2
</div>
<div class="dnd__element dnd__element--dragOver" draggable="true">
Box 3
</div>
</div>
</section>
</body>
</html>
最简单的方法是依赖“handleDragStart()”,因为它只能用 3 个有效项目中的 1 个来调用。因此,在该处理程序中设置一个测试变量(例如 started = true;
)并在“handleDragEnter()”和“[=27=”中检查它 (if (started)
) ]handleDrop()'.
(在'handleDrop()'中将'started'重置为false)...
工作示例:
var started = false;
let dragSrcEl = null;
function handleDragStart(e) {
this.classList.add('dnd__element--dragStart');
started = true;
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDragEnter(e) {
if (started) this.classList.add('dnd__element--dragOver');
}
function handleDragLeave(e) {
this.classList.remove('dnd__element--dragOver');
}
function handleDragEnd(e) {
this.classList.remove('dnd__element--dragStart');
items.forEach(function(item) {
item.classList.remove('dnd__element--dragOver');
});
started = false;
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
if (started && dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
started = false;
return false;
}
const items = document.querySelectorAll('.dnd__element');
items.forEach(function(item) {
item.classList.remove(
'dnd__element--dragStart',
'dnd__element--dragEnd',
'dnd__element--dragOver'
);
item.addEventListener('dragstart', handleDragStart, false);
item.addEventListener('dragover', handleDragOver, false);
item.addEventListener('dragenter', handleDragEnter, false);
item.addEventListener('dragleave', handleDragLeave, false);
item.addEventListener('drop', handleDrop, false);
item.addEventListener('dragend', handleDragEnd, false);
});
.dnd__element {
cursor: move;
border: 3px solid #777;
background-color: #ddd;
padding: 1rem;
border-radius: 0.5rem;
float: left;
}
.dnd__element--dragStart {
opacity: 0.4;
}
.dnd__element--dragEnd {
opacity: 1;
}
.dnd__element--dragOver {
border: 3px dotted #666;
}
.dnd__drag-zone {
height: 20rem;
background-color: cornsilk;
}
.heading-tertiary {
display: block;
background-color: darkkhaki;
padding: 2rem 1rem;
}
<section class="section-dnd">
<div class="dnd__drag-zone">
<h3 class="heading-tertiary">Drag zone</h3>
<div class="dnd__element dnd__element--dragStart" id="d1" draggable="true">
Box 1
</div>
<div class="dnd__element dnd__element--dragEnd" id="d2" draggable="true">
Box 2
</div>
<div class="dnd__element dnd__element--dragOver" draggable="true">
Box 3
</div>
</div>
</section>
在这些天里,我一直在尝试学习如何实现拖放 API,但我 运行 遇到了一个我无法修复的错误。实际上,如果我通过拖动交换第一个和第二个框,当我 select 和 header 并将其拖动到第二个框时,就会发生错误!这只是个案,但还有更多。我想看看调试会发生什么,但我错过了一些东西。下面是错误和代码的屏幕截图:
bug
let dragSrcEl = null;
function handleDragStart(e) {
this.classList.add('dnd__element--dragStart');
console.log(this);
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDragEnter(e) {
this.classList.add('dnd__element--dragOver');
}
function handleDragLeave(e) {
this.classList.remove('dnd__element--dragOver');
}
function handleDragEnd(e) {
this.classList.remove('dnd__element--dragStart');
items.forEach(function(item) {
item.classList.remove('dnd__element--dragOver');
});
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
if (dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
return false;
}
const items = document.querySelectorAll('.dnd__element');
items.forEach(function(item) {
item.classList.remove(
'dnd__element--dragStart',
'dnd__element--dragEnd',
'dnd__element--dragOver'
);
item.addEventListener('dragstart', handleDragStart, false);
item.addEventListener('dragover', handleDragOver, false);
item.addEventListener('dragenter', handleDragEnter, false);
item.addEventListener('dragleave', handleDragLeave, false);
item.addEventListener('drop', handleDrop, false);
item.addEventListener('dragend', handleDragEnd, false);
});
.dnd__element {
cursor: move;
border: 3px solid #777;
background-color: #ddd;
padding: 1rem;
border-radius: 0.5rem;
float: left;
}
.dnd__element--dragStart {
opacity: 0.4;
}
.dnd__element--dragEnd {
opacity: 1;
}
.dnd__element--dragOver {
border: 3px dotted #666;
}
.dnd__drag-zone {
height: 20rem;
background-color: cornsilk;
}
.heading-tertiary {
display: block;
background-color: darkkhaki;
padding: 2rem 1rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<section class="section-dnd">
<div class="dnd__drag-zone">
<h3 class="heading-tertiary">Drag zone</h3>
<div class="dnd__element dnd__element--dragStart" id="d1" draggable="true">
Box 1
</div>
<div class="dnd__element dnd__element--dragEnd" id="d2" draggable="true">
Box 2
</div>
<div class="dnd__element dnd__element--dragOver" draggable="true">
Box 3
</div>
</div>
</section>
</body>
</html>
最简单的方法是依赖“handleDragStart()”,因为它只能用 3 个有效项目中的 1 个来调用。因此,在该处理程序中设置一个测试变量(例如 started = true;
)并在“handleDragEnter()”和“[=27=”中检查它 (if (started)
) ]handleDrop()'.
(在'handleDrop()'中将'started'重置为false)...
工作示例:
var started = false;
let dragSrcEl = null;
function handleDragStart(e) {
this.classList.add('dnd__element--dragStart');
started = true;
dragSrcEl = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/html', this.innerHTML);
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'move';
return false;
}
function handleDragEnter(e) {
if (started) this.classList.add('dnd__element--dragOver');
}
function handleDragLeave(e) {
this.classList.remove('dnd__element--dragOver');
}
function handleDragEnd(e) {
this.classList.remove('dnd__element--dragStart');
items.forEach(function(item) {
item.classList.remove('dnd__element--dragOver');
});
started = false;
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
if (started && dragSrcEl != this) {
dragSrcEl.innerHTML = this.innerHTML;
this.innerHTML = e.dataTransfer.getData('text/html');
}
started = false;
return false;
}
const items = document.querySelectorAll('.dnd__element');
items.forEach(function(item) {
item.classList.remove(
'dnd__element--dragStart',
'dnd__element--dragEnd',
'dnd__element--dragOver'
);
item.addEventListener('dragstart', handleDragStart, false);
item.addEventListener('dragover', handleDragOver, false);
item.addEventListener('dragenter', handleDragEnter, false);
item.addEventListener('dragleave', handleDragLeave, false);
item.addEventListener('drop', handleDrop, false);
item.addEventListener('dragend', handleDragEnd, false);
});
.dnd__element {
cursor: move;
border: 3px solid #777;
background-color: #ddd;
padding: 1rem;
border-radius: 0.5rem;
float: left;
}
.dnd__element--dragStart {
opacity: 0.4;
}
.dnd__element--dragEnd {
opacity: 1;
}
.dnd__element--dragOver {
border: 3px dotted #666;
}
.dnd__drag-zone {
height: 20rem;
background-color: cornsilk;
}
.heading-tertiary {
display: block;
background-color: darkkhaki;
padding: 2rem 1rem;
}
<section class="section-dnd">
<div class="dnd__drag-zone">
<h3 class="heading-tertiary">Drag zone</h3>
<div class="dnd__element dnd__element--dragStart" id="d1" draggable="true">
Box 1
</div>
<div class="dnd__element dnd__element--dragEnd" id="d2" draggable="true">
Box 2
</div>
<div class="dnd__element dnd__element--dragOver" draggable="true">
Box 3
</div>
</div>
</section>