๐ Tutorial : HTML Drag and Drop API
<!-- html ๋ฌธ์ -->
<section class="draggable-elements">
<img
src="love.png"
draggable="true"
class="draggable"
id="love"
data-color="#6CBDF4"
/>
<img
src="seoul.png"
draggable="true"
class="draggable"
id="seoul"
data-color="#2D2B50"
/>
<img
src="clock.png"
draggable="true"
class="draggable"
id="clock"
data-color="#DAF7A6"
/>
<img
src="rod.png"
draggable="true"
class="draggable"
id="rod"
data-color="#DED2C6"
/>
</section>
<section class="droppable-elements">
<div class="droppable" data-draggable-id="love">
<span>์ฌ๋ ์ฌ๋</span>
</div>
<div class="droppable" data-draggable-id="seoul">
<span>์์ธ ๊ฐ ์ด์</span>
</div>
<div class="droppable" data-draggable-id="clock">
<span>์๊ณ๋ฐ๋</span>
</div>
<div class="droppable" data-draggable-id="rod"><span>ํ์ด๋ฆฌ</span></div>
</section>
draggable=true
๋ก ์ค์ ํฉ๋๋ค. ์ ๋ต ํ์ธ์ ์ํด id ๊ฐ
์ ์ง์ ํ๊ณ , data- ์์ฑ
์ ํตํด ์ปฌ๋ฌ๊ฐ์ ์ถ๊ฐํ์์ต๋๋ค.data- ์์ฑ
์ ํตํด id ๊ฐ์ ์ ์ฅํ์์ต๋๋ค.const draggableElements = document.querySelectorAll(".draggable");
const droppableElements = document.querySelectorAll(".droppable");
draggableElements.forEach((draggable) => {
draggable.addEventListener("dragstart", dragStart);
});
droppableElements.forEach((droppable) => {
droppable.addEventListener("dragenter", dragEnter);
droppable.addEventListener("dragover", dragOver);
droppable.addEventListener("dragleave", dragLeave);
droppable.addEventListener("drop", drop);
});
dragstart
์ด๋ฒคํธ๋ฅผ, ์์์๋ dragenter
, dragover
, dragleave
, drop
์ด๋ฒคํธ๋ฅผ ๋ฌ์์ค๋๋ค.function dragStart(event) {
event.dataTransfer.setData("text", event.target.id);
}
event๊ฐ์ฒด์ dataTransfer
๋ฅผ ํตํด text๋ผ๋ ๋ฐ์ดํฐ์ id๊ฐ์ ์ ์ฅํฉ๋๋ค. ์ฌ๊ธฐ์ ์ค์ ํ data๋ drop ์ด๋ฒคํธ ํธ๋ค๋ฌ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.function dragEnter(event) {
if (!event.target.classList.contains("dropped")) {
event.target.classList.add("droppable-hover");
}
}
function dragOver(event) {
if (!event.target.classList.contains("dropped")) {
event.preventDefault();
}
}
function dragLeave(event) {
if (!event.target.classList.contains("dropped")) {
event.target.classList.remove("droppable-hover");
}
}
๋๋๊ทธ๊ฐ ์์๋๋ฉด ์์์ droppable-hover
ํด๋์ค๋ฅผ ์ถ๊ฐํ์ฌ ์์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ์ ์ ํ
๋๋ฆฌ๋ก ๋ฐ๋๋ css ์คํ์ผ์ ์ ์ฉํด์ค๋๋ค. ๋๋๊ทธ๊ฐ ๋๋๋ฉด ํด๋น ํด๋์ค๋ฅผ ์ ๊ฑฐํฉ๋๋ค
์์์ dropped
๋ผ๋ ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ์๋(์ด๋ฏธ ์บ๋ฆญํฐ ์ด๋ฏธ์ง๊ฐ ๋๋กญ๋ ๊ฒฝ์ฐ์๋) droppable-hover
ํด๋์ค๋ฅผ ์ถ๊ฐํ์ง ์์ต๋๋ค.
dragover
์ด๋ฒคํธ ํธ๋ค๋ฌ์์ event.preventDefault()๋ฅผ ํธ์ถํด์ผ ์ถํ drop ์ด๋ฒคํธ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
function drop(event) {
event.preventDefault();
event.target.classList.remove("droppable-hover");
const draggableElementData = event.dataTransfer.getData("text");
const droppableElementData = event.target.getAttribute("data-draggable-id");
if (draggableElementData === droppableElementData) {
event.target.classList.add("dropped");
const draggableElement = document.getElementById(draggableElementData);
event.target.style.backgroundColor = draggableElement.dataset.color;
draggableElement.classList.add("dragged");
draggableElement.setAttribute("draggable", false);
event.target.insertAdjacentHTML(
"afterbegin",
`<img src="${draggableElementData}.png"/>`
);
}
}
์บ๋ฆญํฐ ์ด๋ฏธ์ง๊ฐ ์์ ์๋ก ๋๋กญ๋ ๊ฒฝ์ฐ ์ ์ฉํ ๋ก์ง์ ๋๋ค.
event.preventDefault()
๋ฅผ ํตํด ๋๋กญ ์ด๋ฒคํธ์ ๊ธฐ๋ณธ๋์์ ๋ง์ต๋๋ค. (์๋ฅผ ๋ค์ด, ๋งํฌ ํ๊ทธ๋ฅผ ์์ ์๋ก ๋๋กญํ ๊ฒฝ์ฐ ๋งํฌ๊ฐ ์ด๋ฆฌ๋ ๋์์ ๋ง์์ค๋๋ค.)
dragstart ์ด๋ฒคํธ์์ ์ค์ ํ dataTransfer
๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ draggableElementData
๋ผ๋ ๋ณ์์ ์ ์ฅํ๊ณ , droppableElementData
์๋ data- ์์ฑ์ ํตํด ์์์ ์ ์ฅํ๋ id๊ฐ์ ๋ถ๋ฌ์ต๋๋ค.
๋ง์ฝ ๋ ๊ฐ์ด ์ผ์นํ๋ฉด, ์์์ dropped
ํด๋์ค๋ฅผ ์ถ๊ฐํ๊ณ ์บ๋ฆญํฐ ์ด๋ฏธ์ง์ ์ ์ฅํ๋ ์ปฌ๋ฌ๊ฐ์ ๊ฐ์ ธ์ ์์ ๋ฐฐ๊ฒฝ์์ ๋ฐ๊ฟ์ค๋๋ค. ์บ๋ฆญํฐ ์ด๋ฏธ์ง์๋ dragged
ํด๋์ค๋ฅผ ์ถ๊ฐํ์ฌ opacity๋ฅผ ์กฐ์ ํ๊ณ , ๋ ์ด์ ๋๋๊ทธํ ์ ์๋๋ก draggable
์์ฑ์ false๋ก ์ค์ ํด์ค๋๋ค.
insertAdjacentHTML
๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์์ ์์ ์ด๋ฏธ์ง ํ๊ทธ๋ฅผ ์ฝ์
ํฉ๋๋ค.