A Pen by Nathan Stanford Sr on CodePen.
Created
April 15, 2022 12:51
-
-
Save nastanford/fa1ad6e8585d3ce63090e23deef15291 to your computer and use it in GitHub Desktop.
JavaScript Drag & Drop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h1>10 Richest People</h1> | |
<p>Drag and drop the items into their corresponding spots</p> | |
<ul class="draggable-list" id="draggable-list"></ul> | |
<button class="check-btn" id="check"> | |
Check Order | |
<svg viewBox="0 0 24 24"> | |
<line x1="22" y1="2" x2="11" y2="13"></line> | |
<polygon points="22 2 15 22 11 13 2 9 22 2"></polygon> | |
</svg> | |
</button> | |
<!-- GitHub: https://github.com/saulgavrilov/js-drag-drop --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const log = console.log; | |
const draggableList = document.getElementById('draggable-list'); | |
const check = document.getElementById('check'); | |
const richestPeople = [ | |
'Jeff Bezos', | |
'Bill Gates', | |
'Warren Buffett', | |
'Bernard Arnault', | |
'Carlos Slim Helu', | |
'Amancio Ortega', | |
'Larry Ellison', | |
'Mark Zuckerberg', | |
'Michael Bloomberg', | |
'Larry Page', | |
]; | |
// Store list items | |
const listItems = []; | |
// Keep track the index of each list item | |
let dragStartIndex; | |
createList(); | |
// This function responsible to generate the list items | |
// "Insert list items into DOM" | |
function createList() { | |
[...richestPeople] | |
.map((a) => ({ value: a, sort: Math.random() })) | |
.sort((a, b) => a.sort - b.sort) | |
.map((c) => c.value) | |
.forEach((person, index) => { | |
const listItem = document.createElement('li'); | |
listItem.setAttribute('data-index', index); | |
listItem.innerHTML = ` | |
<span class="number">${index + 1}</span> | |
<div class="draggable" draggable="true"> | |
<p class="person-name">${person}</p> | |
<svg viewBox="0 0 24 24"> | |
<line x1="8" y1="6" x2="21" y2="6"></line> | |
<line x1="8" y1="12" x2="21" y2="12"></line> | |
<line x1="8" y1="18" x2="21" y2="18"></line> | |
<line x1="3" y1="6" x2="3.01" y2="6"></line> | |
<line x1="3" y1="12" x2="3.01" y2="12"></line> | |
<line x1="3" y1="18" x2="3.01" y2="18"></line> | |
</svg> | |
</div> | |
`; | |
listItems.push(listItem); | |
draggableList.appendChild(listItem); | |
}); | |
addEventListeners(); | |
} | |
function dragStart() { | |
// log('Event: ', 'dragStart'); | |
dragStartIndex = +this.closest('li').getAttribute('data-index'); | |
// log(dragStartIndex); | |
} | |
function dragOver(e) { | |
// log('Event: ', 'dragOver'); | |
e.preventDefault(); | |
} | |
function dragDrop() { | |
// log('Event: ', 'dragDrop'); | |
const dragEndIndex = +this.getAttribute('data-index'); | |
swapItems(dragStartIndex, dragEndIndex); | |
this.classList.remove('over'); | |
} | |
// Swap list items that are drag and drop | |
function swapItems(from, to) { | |
const itemOne = listItems[from].querySelector('.draggable'); | |
const itemTwo = listItems[to].querySelector('.draggable'); | |
listItems[from].appendChild(itemTwo); | |
listItems[to].appendChild(itemOne); | |
} | |
function dragEnter() { | |
// log('Event: ', 'dragEnter'); | |
this.classList.add('over'); | |
} | |
function dragLeave() { | |
// log('Event: ', 'dragLeave'); | |
this.classList.remove('over'); | |
} | |
// Check the order of list items | |
function checkOrder() { | |
listItems.forEach((listItem, index) => { | |
const personName = listItem.querySelector('.draggable').innerText.trim(); | |
if (personName !== richestPeople[index]) { | |
listItem.classList.add('wrong'); | |
} else { | |
listItem.classList.add('right'); | |
listItem.classList.remove('wrong'); | |
} | |
}); | |
} | |
function addEventListeners() { | |
const draggables = document.querySelectorAll('.draggable'); | |
const dragListItems = document.querySelectorAll('.draggable-list li'); | |
draggables.forEach((draggable) => { | |
draggable.addEventListener('dragstart', dragStart); | |
}); | |
dragListItems.forEach((item) => { | |
item.addEventListener('dragover', dragOver); | |
item.addEventListener('drop', dragDrop); | |
item.addEventListener('dragenter', dragEnter); | |
item.addEventListener('dragleave', dragLeave); | |
}); | |
} | |
check.addEventListener('click', checkOrder); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:root { | |
--main-color: #037fff; | |
--text-color: #34444f; | |
--bg-dark: #10121b; | |
--secondary-dark: #2e344e; | |
} | |
*, | |
*::before, | |
*::after { | |
box-sizing: border-box; | |
margin: 0; | |
padding: 0; | |
} | |
body { | |
display: flex; | |
align-items: center; | |
justify-content: flex-start; | |
flex-direction: column; | |
height: 100vh; | |
font-family: sans-serif; | |
} | |
body > h1, | |
body > p { | |
padding: 0.8rem; | |
} | |
svg { | |
width: 24px; | |
height: 24px; | |
stroke: currentColor; | |
stroke-width: 2; | |
fill: none; | |
stroke-linecap: round; | |
stroke-linejoin: round; | |
} | |
.draggable-list { | |
border: 1px solid var(--secondary-dark); | |
color: var(--text-color); | |
list-style-type: none; | |
} | |
.draggable-list li { | |
background: #ffffff; | |
display: flex; | |
flex: 1; | |
} | |
.draggable-list li:not(:last-of-type) { | |
border-bottom: 1px solid var(--secondary-dark); | |
} | |
.draggable-list .number { | |
background: var(--bg-dark); | |
color: #ffffff; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
font-size: 1.2rem; | |
height: 60px; | |
width: 60px; | |
} | |
.draggable-list .person-name { | |
margin: 0 1rem 0 0; | |
} | |
.draggable-list li.right .person-name { | |
color: #3ae374; | |
} | |
.draggable-list li.wrong .person-name { | |
color: #ff3838; | |
} | |
.draggable-list li.over { | |
border-bottom: none; | |
} | |
.draggable-list li.over .draggable { | |
background: #c7c7c7; | |
} | |
.draggable { | |
cursor: pointer; | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
padding: 1rem; | |
flex: 1; | |
} | |
.check-btn { | |
background: var(--bg-dark); | |
color: #ffffff; | |
border: none; | |
outline: none; | |
padding: 0.8rem 1rem; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
margin-top: 1rem; | |
cursor: pointer; | |
} | |
.check-btn:active { | |
transform: scale(0.98); | |
} | |
.check-btn svg { | |
margin-left: 0.5rem; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment