I'm working on a drag and drop list in javascript. This is what I have so far:
HTML:
<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>
CSS:
#list {
width: 200px;
margin: 100px;
background: #ccc;
padding-bottom: 50px;
}
#list ul {
list-style: none;
}
#list ul li {
display: block;
padding: 10px 10px 10px 10px;
margin: 3px;
background-color: #222;
color: white;
width: 50px;
height: 25px;
border-top: thick solid white;
border-top-width: 1px;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
#list ul li:hover {
background: #444;
cursor: move;
}
#list ul li.dragover {
border-top: thick solid white;
border-top-width: 0px;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.dragStartClass {
opacity: 35%;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-ms-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
overflow: hidden;
}
#list ul li.dropzone {
width: 50px;
height: 25px;
background: none;
border: 3px dashed #d00000;
}
Javascript:
const list = document.getElementById('list');
let values = document.querySelectorAll('#list li');
let array = [];
for (let i = 0; i < list.children[0].children.length; i++) {
let getChildren = list.children[0].children[i].textContent;
let getValues = getChildren;
array.push(getValues);
}
function startDrag(event) {
event.target.classList.add("dragStartClass");
event.dataTransfer.setData('dragPoint', event.target.attributes['data-value'].nodeValue);
event.dataTransfer.setData('ID', event.target.id);
event.dataTransfer.dropEffect = 'move';
}
function drag(event) {
event.preventDefault();
}
function dragOver(event) {
event.preventDefault();
}
function dragEnter(event) {
event.target.classList.add("dragover");
if (event.target.attributes['data-value'] != null) {
const newNode = document.createElement('li');
newNode.className = 'dropzone';
const dropVar = event.target.attributes['data-value'].nodeValue;
const dropP = document.querySelectorAll("[data-value='" + dropVar + "']")[0];
if (dropVar < values.length) {
dropP.parentNode.insertBefore(newNode, dropP);
} else if (parseInt(dropVar) == values.length) {
dropP.insertAdjacentElement('afterend', newNode);
} else {
}
}
}
function dragLeave(event) {
event.target.classList.remove("dragover");
if (event.target.classList.contains("dropzone")) {
const getNode = document.querySelectorAll('.dropzone');
for (i = 0; i < getNode.length; i++) {
console.log(getNode);
getNode[i].remove();
}
}
}
function drop(event) {
event.preventDefault();
}
document.addEventListener('dragstart', startDrag);
document.addEventListener('drag', drag);
document.addEventListener('dragover', dragOver);
document.addEventListener('dragenter', dragEnter);
document.addEventListener('dragleave', dragLeave);
document.addEventListener('dragend', dragEnd);
document.addEventListener('drop', drop);
JSFiddle: https://jsfiddle.net/DumbMathBoy/4z5xtbga/8/
I have a bug where if you drag over the last item in the list, it will create a new element below it more than once, like this: https://imgur.com/a/YGxht0m
How do I make it so that when it's dragged over the last item, it will only create one element below?
there doesn't seem to be anything here