<!--
...
-->
<ul class="list-group">
<option class="list-item" value=1>Option 1</option>
<option class="list-item" value=2>Option 2</option>
<option class="list-item" value=3>Option 3</option>
</ul>
<!--
...
-->
<!--
...
-->
<ul class="list-group">
<option class="list-item" draggable=true value=0>Option 1</option>
<option class="list-item" draggable=true value=1>Option 2</option>
<option class="list-item" draggable=true value=2>Option 3</option>
</ul>
<!--
...
-->
const list = document.querySelector(".list-group").children;
// Node, 인덱스를 저장해줄 변수
let draggingNode = null;
let draggingIndex = null;
// 드래그를 시작할 때 드래그 중인 element의 정보를 저장해주는 Event 등록
for (let node of list) {
node.addEventListener("dragstart", (event) => {
const {
target: { value }
} = event;
for (let i = 0; i < list.length; i++) {
const node = list[i];
if (node.value === value) {
draggingNode = node;
draggingIndex = i;
break;
}
}
});
}
node.addEventListener("dragenter", (event) => {
// 스왑할 노드 정보 가져오기
const {
target: { value }
} = event;
const { target: targetNode } = event;
let targetIndex = null;
for (let i = 0; i < list.length; i++) {
const node = list[i];
if (node.value === value) {
targetIndex = i;
break;
}
}
// 노드 스왑
if (draggingIndex !== null && targetIndex !== null) {
// 자신이 제일 위에 있게 될 때에는 before 메서드 사용
targetIndex === 0
? targetNode.before(draggingNode)
: targetNode.after(draggingNode);
}
});
node.addEventListener("dragend", () => {
draggingNode = null;
draggingIndex = null;
});
node.addEventListener("dragover", (event) => {
event.preventDefault();
});
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<ul class="list-group">
<option class="list-item" draggable="true" value="1">Option 1</option>
<option class="list-item" draggable="true" value="2">Option 2</option>
<option class="list-item" draggable="true" value="3">Option 3</option>
</ul>
<script src="index.js"></script>
</body>
</html>
JS
import "./styles.css";
const list = document.querySelector(".list-group").children;
let draggingNode = null;
let draggingIndex = null;
for (let node of list) {
node.addEventListener("dragstart", (event) => {
const {
target: { value }
} = event;
for (let i = 0; i < list.length; i++) {
const node = list[i];
if (node.value === value) {
draggingNode = node;
draggingIndex = i;
break;
}
}
});
node.addEventListener("dragenter", (event) => {
const {
target: { value }
} = event;
const { target: targetNode } = event;
let targetIndex = null;
for (let i = 0; i < list.length; i++) {
const node = list[i];
if (node.value === value) {
targetIndex = i;
break;
}
}
if (draggingIndex !== null && targetIndex !== null) {
targetIndex === 0
? targetNode.before(draggingNode)
: targetNode.after(draggingNode);
}
});
node.addEventListener("dragend", () => {
draggingNode = null;
draggingIndex = null;
});
node.addEventListener("dragover", (event) => {
event.preventDefault();
});
}
출처:
https://ko.javascript.info/bubbling-and-capturing
https://developer.mozilla.org/ko/docs/Web/API/HTML_Drag_and_Drop_API