Drag-drop
by Julien Roche
HTML
<article class="drop-container">
<div class="drag-item" draggable="false" data-id="id-1">
<span class="drag-item__icon">Icon</span>
<span> </span>
<span>A1</span>
</div>
<div class="drag-item" draggable="false" data-id="id-2">
<span class="drag-item__icon">Icon</span>
<span> </span>
<span>A2</span>
</div>
<div class="drag-item" draggable="false" data-id="id-3">
<span class="drag-item__icon">Icon</span>
<span> </span>
<span>A3</span>
</div>
<div class="drag-item" draggable="false" data-id="id-4">
<span class="drag-item__icon">Icon</span>
<span> </span>
<span>A4</span>
</div>
</article>
CSS
html,
body {
height: 100%;
margin: 0 0 0 0;
padding: 0 0 0 0;
}
body {
background-color: grey;
display: flex;
margin: 1rem;
}
.drop-container {
background-color: white;
flex: 1 1 auto;
margin: 1rem;
}
.drag-item {
background-color: orange;
height: 2rem;
margin: 1rem;
user-select: none;
&.drag-item--drag {
background-color: aqua;
}
&.drag-item--dragenter {
opacity: 0.25;
}
& .drag-item__icon {
background: red;
cursor: move;
}
}
JavaScript
const iconElements = Array.from(document.querySelectorAll('.drag-item__icon'));
iconElements.forEach((element) => {
const draggableParentElement = element.closest('.drag-item');
element.addEventListener('pointerenter', () => {
draggableParentElement.setAttribute('draggable', 'true');
}, false);
element.addEventListener('pointerleave', () => {
draggableParentElement.setAttribute('draggable', 'false');
}, false);
});
const draggableElements = Array.from(document.querySelectorAll('.drag-item'));
draggableElements.forEach((element) => {
element.addEventListener('dragstart', (event) => {
element.classList.add('drag-item--drag');
event.dataTransfer.setData('text/plain', element.dataset.id);
event.dataTransfer.dropEffect = 'copy';
event.dataTransfer.dropEffect = 'copy';
}, false);
element.addEventListener('dragend', () => {
element.classList.remove('drag-item--drag');
element.classList.remove('drag-item--dragenter');
}, false);
element.addEventListener('dragenter', (event) => {
if (element.classList.contains('drag-item--drag')) {
return;
}
element.classList.add('drag-item--dragenter');
}, false);
element.addEventListener('dragleave', (event) => {
if (element.classList.contains('drag-item--drag')) {
return;
}
element.classList.remove('drag-item--dragenter');
}, false);
element.addEventListener('drop', (event) => {
event.preventDefault();
const id = event.dataTransfer.getData('text/plain');
const elementToMove = document.querySelector(`[data-id="${id}"]`)
element.after(elementToMove);
element.classList.remove('drag-item--dragenter');
}, false);
});
const dropContainerElement = document.querySelector('.drop-container')
dropContainerElement.addEventListener('dragover', (event) => {
event.preventDefault();
}, false);
dropContainerElement.addEventListener('dragleave', (event) => {
...