JS - drag and drop
이벤트 및 순서 | 설명 |
dragstart | 드래그가 시작될 때 |
dragenter | 드래그된 요소가 드롭 가능 영역에 처음으로 진입했을 때 |
dragover | 드래그된 요소가 드롭 가능 영역 위에 있을 때 / event.preventDefault() 필요 |
dragleave | 드래그된 요소가 드롭 가능 영역에서 벗어났을 때 |
drop | 드래그된 요소가 드롭 가능 영역에 놓였을 때 / event.preventDefault() 필요 |
event.preventDefault()
기본 동작을 방지함
- 폼 제출 방지
- 링크 클릭 시 페이지 이동 방지
- 드래그 앤 드롭 가능
작성순서
1. 변수 선언
드래그 요소, 드롭 영역
2. 이벤트 생성
2-1. 드래그 요소
모든 드래그 요소에 이벤트를 지정해
드래그를 시작했을 때, 드래그를 끝 마쳤을 때 각각 start, end 함수를 호출
2-2. 드롭 영역
2-2-1
요소를 드래그 해서 드롭 영역에 마우스 커서를 올리면 (dragover) 함수 호출하는 이벤트 생성
e.preventDefault() // 기본 동작 방지/
폼 제출 방지, 링크 클릭시 페이지 이동 방지, 드롭 불가능 상태 해제
hovered class 지정
2-2-2
드래그 요소가 드롭 가능한 위치를 벗어났을 때 이벤트 생성 (dragleave) hover class 제거
2-2-3
드래그 요소를 (drop)했을 때 함수 호출하는 이벤트 생성
e.preventDefault();
dragging class를 선택하여 변수에 저장
해당 변수를 appnedChild로 드롭 영역에 자식 요소로 설정
마지막으로 hover class 제거
3. 함수 생성
3-1. start함수 호출시
클릭한 요소에 dragging class 생성
3-2 end함수 호출시
클릭한 요소에서 dragging class 제거
HTML
드래그하려는 태그에 draggable="true"
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./drag.css">
</head>
<body>
<div class="dragZone">
<p class="draggble" draggable="true">드래그 1</p>
<p class="draggble" draggable="true">드래그 2</p>
<p class="draggble" draggable="true">드래그 3</p>
</div>
<div class="dropZone">
<p>여기에 드롭하세요</p>
</div>
<script src="./drag.js"></script>
</body>
</html>
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.dragZone {
display: flex;
}
.dragZone p {
border: 2px solid greenyellow;
border-radius: 10px;
background-color: green;
color: white;
font-size: 30px;
width: 200px;
height: 100px;
margin: 10px;
padding: 25px;
}
.dropZone {
width: auto;
height: 200px;
font-size: 30px;
border: 2px dashed green;
padding: 20px;
display: flex;
}
.hovered {
color: white;
background-color: black;
}
.dragging {
opacity: 0.5;
}
JS
// 최종 목표 : 드래그 요소를 드래그하여 드롭 영역에 놓으면 해당 영역에 붙여넣기 됨.
// 1.드래그 가능한 모든 요소를 선택
// 2.드롭 영역 선택
// 3.드래그 가능한 모든 요소에 dragstart, dragend시 함수 호출하는 이벤트 생성
// 4.dragstart, dragend 이벤트로 호출된 함수에 드래그된 요소의 클래스 생성 및 제거
// 5.요소를 드롭 했을 때 dragstart로 생성된 class를 선택해 변수에 저장 후에 appedChild 로 드롭 영역에 붙여넣음
//
// 추가 : 요소를 드래그시 기존 요소에 opacity를 적용해야함
// 요소를 드래그하고 드롭 영역에 hover시에 드롭 영역의 배경색이 바뀜
// 셀렉트
let draggble = document.querySelectorAll(".draggble"); //드래그 가능한 모든 요소 선택
// console.log(draggble.length);
let dropZone = document.querySelector(".dropZone"); //드롭 영역 선택
// 이벤트
// 모든 드래그 요소에 이벤트를 지정해줘야하기 때문에 반복문 사용
for(let i = 0; i < draggble.length; i++) {
draggble[i].addEventListener("dragstart", handleDragStart);
draggble[i].addEventListener("dragend", handleDragEnd);
}
// 아이탬을 드롭존으로 드래그하고 드롭했을 때 그리고 드래그가 끝났을 때 hover class를 없애고, 드롭한 아이템을 드롭존에 appendChild로 추가한다.
dropZone.addEventListener("dragover", function(e) {
e.preventDefault(); //기본 동작 방지/ 폼 제출 방지, 페이지 이동 방지, 드롭 불가능 상태 해제
dropZone.classList.add("hovered");
});
dropZone.addEventListener("dropleave", function() {
dropZone.classList.remove("hovered");
});
// 아이템을 드래그 시작했을 때 dragging 클래스가 붙는다, 고로
// dropZone 내부에서 querySelector("dragging");하면 내가 드래그하고 있는 아이템이 선택된다.
dropZone.addEventListener("drop", function(e) {
e.preventDefault();
let dragging = document.querySelector(".dragging");
dropZone.appendChild(dragging);
dropZone.classList.remove("hovered");
});
//아이템을 드롭존에 드롭하고 난 후 해당 아이템에 대한 처리 (제거)
function handleDragStart() {
this.classList.add("dragging");
}
function handleDragEnd() {
this.classList.remove("dragging");
}
'dragstart', 'dragend'이벤트로 호출한 함수에 "dragging" class를 생성 및 제거하는 이유는 해당 요소에 스타일을 지정해 꾸미는 역할도 하지만, "drop"시에 "dragging" class가 있는 요소를 선택해 그 요소를 "dropZone" 드롭 영역에 자식요소로 하기 위한 것이 크다.
![]() |