I'm trying to make a drag-and-drop list, when I drag I want the dropzone to be inserted above the previous element. The dropzone needs to be inserted above the previous element.
The problem I have is when an item is dragged, it will constantly insert and then delete it. How can I insert a dropzone without that flicker?
EDIT: It seems I only get this problem in Firefox.
let list = document.querySelectorAll('#list ul li');
let counter;
function startDrag(event) {
event.target.classList.add("dragStartClass");
event.dataTransfer.setData('dragPoint', event.target.attributes['data-value'].nodeValue);
event.dataTransfer.dropEffect = 'move';
}
function dragEnter(event) {
counter = 0;
event.preventDefault();
if (event.target.localName == 'li' && event.target.attributes['data-value'] != null) {
let dropPosition = event.target.attributes['data-value'].nodeValue;
let draggedItem = event.dataTransfer.getData('dragPoint');
let dropTarget = document.querySelectorAll("[data-value='" + dropPosition + "']")[0];
let dropNode = document.createElement('li');
dropNode.className = 'dropzone';
dropTarget.insertAdjacentElement('beforebegin', dropNode);
counter++;
}
}
function dragLeave(event) {
if (counter === 0) {
let dropzone = document.querySelectorAll(".dropzone")[0];
if (dropzone !== undefined) {
dropzone.remove();
}
}
}
document.addEventListener('dragstart', startDrag);
document.addEventListener('dragenter', dragEnter, false);
document.addEventListener('dragleave', dragLeave, false);
#list ul li {
width: 150px;
background: #000;
color: #fff;
padding: 10px 12px;
margin: 0px 0px 10px 0px;
}
#list ul li.dropzone {
width: 44px;
height: 25px;
background: none;
border: 3px dashed #222;
opacity: 35%;
-webkit-transition: all 0.5s ease-out;
-moz-transition: all 0.5s ease-out;
-ms-transition: all 0.5s ease-out;
-o-transition: all 0.5s ease-out;
transition: all 0.5s ease-out;
}
<div id="list">
<ul>
<li draggable="true" data-value="1">1</li>
<li draggable="true" data-value="2">2</li>
<li draggable="true" data-value="3">3</li>
<li draggable="true" data-value="4">4</li>
</ul>
</div>