<!-- html λ¬Έμ -->
<section class="container">
<div class="draggable" draggable="true">
<span class="text">μ‘μΈ</span>
<i class="fas fa-bars"></i>
</div>
<div class="draggable" draggable="true">
<span class="text">무μ¬μΈμ</span>
<i class="fas fa-bars"></i>
</div>
<div class="draggable" draggable="true">
<span class="text">νμ΄λ¦¬</span>
<i class="fas fa-bars"></i>
</div>
<div class="draggable" draggable="true">
<span class="text">μμΈ κ° μ΄μ</span>
<i class="fas fa-bars"></i>
</div>
<div class="draggable" draggable="true">
<span class="text">μ΄λ³νΈμ§</span>
<i class="fas fa-bars"></i>
</div>
<div class="draggable" draggable="true">
<span class="text">κ°μμ€</span>
<i class="fas fa-bars"></i>
</div>
</section>
draggable μμ±μ trueλ‘ μ§μ
νμ¬ λλκ·Έ ν μ μκ² λ§λ€μ΄ μ€λλ€.// js νμΌ
const draggables = document.querySelectorAll(".draggable");
draggables.forEach((draggable) => {
draggable.addEventListener("dragstart", () => {
draggable.classList.add("dragging");
});
draggable.addEventListener("dragend", () => {
draggable.classList.remove("dragging");
});
});
querySelectorAllμ ν΅ν΄ ν΄λμ€λͺ
μ΄ draggableμΈ μμλ€μ μ νν ν, forEachλ¬Έμ ν΅ν΄ κ° μμμ dragstart
, dragend
μ΄λ²€νΈ νΈλ€λ¬λ₯Ό λ¬μμ€λλ€.
λλκ·Έκ° μμλλ©΄ dragging ν΄λμ€λ₯Ό λ¬μμ£Όκ³ , λλκ·Έκ° λλλ©΄ dragging ν΄λμ€λ₯Ό μ κ±°ν©λλ€. cssλ₯Ό ν΅ν΄ dragging ν΄λμ€κ° λ¬λ¦° λ Έλ μ λͺ©μ opacityλ₯Ό μ‘°μ ν΄ λΆν¬λͺ νκ² λ§λ€μ΄ μ€λλ€.
container.addEventListener("dragover", (e) => {
e.preventDefault();
const draggable = document.querySelector(".dragging");
const afterElement = getDragAfterElement(container, e.clientY);
container.insertBefore(draggable, afterElement);
});
컨ν
μ΄λμλ dragover
μ΄λ²€νΈ νΈλ€λ¬λ₯Ό λ¬μμ€λλ€. 컨ν
μ΄λ μλ‘ λ¬΄μΈκ°κ° λλκ·Έ λ λ λ°μνλ μ΄λ²€νΈμ
λλ€.
e.preventDefault()
λ₯Ό νΈμΆν΄μΌ λμ€μ drop μ΄λ²€νΈλ₯Ό λ°μ μ μμ΅λλ€.
λλκ·Έ ν λ μ€μκ°μΌλ‘ μμ μμΉλ₯Ό λ°κΏμ€λλ€.
νμ¬ draggingνκ³ μλ λ
Έλλ₯Ό μ ννμ¬ ν΄λΉ λ
Έλμ λ°λ‘ μλμ μλ μμ μμ λ£μ΄μ€λλ€.
function getDragAfterElement(container, y) {
const draggableElements = [
...container.querySelectorAll(".draggable:not(.dragging)"),
];
return draggableElements.reduce(
(closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
},
{ offset: Number.NEGATIVE_INFINITY }
).element;
}
νμ¬ λλκ·Ένκ³ μλ μμμ λ°λ‘ λ°μ μλ μμλ₯Ό μ°Ύμλ΄λ λ‘μ§μ
λλ€. reduce ν¨μ
λ₯Ό μ΄μ©νμ¬ draggableν μμλ€μ μ°¨λ‘λλ‘ λλ©΄μ offset κ°
λΉκ΅λ₯Ό ν΅ν΄ κ°μ₯ κ°κΉμ΄ μμλ₯Ό μ°Ύμλ
λλ€.
offset κ°μ΄ μμ
μ΄λ©΄ νμ¬ λλκ·Ένκ³ μλ λ
Έλλ³΄λ€ μμ μλ μμ
μ΄κ³ , offset κ°μ΄ μμ
μ΄λ©΄ νμ¬ λλκ·Ένκ³ μλ λ
Έλλ³΄λ€ μλμ μμΉνλ μμ
μ
λλ€.
offset κ°μ΄ μμμ΄λ©΄μ(μλμ μλ μμμ΄λ©΄μ), νμ¬ κ°μ₯ κ°κΉμ΄ μμμ offset κ°λ³΄λ€ offset κ°μ΄ ν΄ λ(μμμ΄κΈ° λλ¬Έμ κ°μ΄ μ»€μΌ κ°μ₯ κ°κΉμ΄ μμμ) offset κ°κ³Ό ν΄λΉ μμλ₯Ό κ°μ²΄λ‘ λ°νν©λλ€.
container.addEventListener("drop", () => {
const correctArray = [
"νμ΄λ¦¬",
"무μ¬μΈμ",
"μ‘μΈ",
"κ°μμ€",
"μ΄λ³νΈμ§",
"μμΈ κ° μ΄μ",
];
const draggables = container.querySelectorAll(".draggable");
const currentArray = [...draggables].map((draggable) => draggable.innerText);
const equals = (a, b) => JSON.stringify(a) === JSON.stringify(b);
if (equals(correctArray, currentArray)) {
container.style.backgroundColor = "lavenderblush";
alert("μ λ΅μ
λλ€π");
}
});
컨ν
μ΄λμ drop
μ΄λ²€νΈ νΈλ€λ¬λ₯Ό λ¬μμ€λλ€. dropν λλ§λ€ νμ¬ λ
Έλ μμκ° μ λ΅μΈμ§λ₯Ό νμΈνμ¬, μ λ΅μΈ κ²½μ° μ»¨ν
μ΄λμ λ°°κ²½μμ λ³κ²½νκ³ μ λ΅ μλ¦Όμ λμμ€λλ€.
νμ¬ λ°°μ΄κ³Ό μ λ΅ λ°°μ΄μ λΉκ΅ν λλ λλ± μ°μ°μ(==)λ₯Ό ν΅ν λΉκ΅κ° λΆκ°λ₯
νλ―λ‘(λ°°μ΄μ μ°Έμ‘°νμ΄κΈ° λλ¬Έμ κ°μ΄ μλ μ£Όμκ°μ λΉκ΅ν©λλ€.) JSON.stringify() λ©μλ
λ₯Ό ν΅ν΄ λ°°μ΄μ λ¬Έμμ΄ννμ¬ λΉκ΅ν©λλ€.