드래그 앤 드롭(Drag & Drop) 기능 학습

My Pale Blue Dot·2025년 2월 17일

JAVASCRIPT

목록 보기
11/26
post-thumbnail

📅 날짜

2025년 2월 17일

📖 학습 내용

📝 드래그 앤 드롭(Drag & Drop) 이벤트 이해

드래그 앤 드롭 기능을 구현하기 위해 다음 이벤트를 활용함.

이벤트명설명
dragstart드래그 시작 (요소를 클릭 후 끌 때)
drag드래그 중
dragenter드래그된 요소가 대상 영역 위로 이동할 때
dragover드래그된 요소가 대상 영역 위에 있는 동안
dragleave드래그된 요소가 대상 영역에서 벗어날 때
dragend드래그 종료
drop드랍 (마우스를 놓았을 때 데이터 처리)

🖼️ 파일 업로드 및 유효성 검사

  • 최대 업로드 크기를 1MB로 제한
  • 이미지 파일만 허용 (file.type.startsWith("image/"))
  • drop 이벤트에서 파일을 받아 미리보기 이미지 표시

🔹 유효성 검사 코드

function isValid(file) {
    if (!file.type.startsWith("image/")) {
        alert("이미지 파일만 업로드 가능합니다.");
        return false;
    } else if (file.size >= (1024 * 1024 * 1)) {
        alert("파일 업로드의 최대 사이즈는 1MB입니다.");
        return false;
    }
    return true;
}

🎨 HTML & CSS 레이아웃 구성

드래그할 수 있는 아이템(.items)과 드롭할 수 있는 .board 영역을 배치하는 구조를 만들었음.
사이드바에는 드래그 가능한 항목이 있고, 사용자가 드래그하여 .board에 드롭하면 새로운 요소가 추가됨.

🔹 레이아웃 예제 코드

<div class="wrapper">
    <header></header>
    <main>
        <section>
            <!-- 사이드바 -->
            <aside>
                <ul class="items">
                    <li><a href="#" draggable="true" class="item-style-1">ITEM_1</a></li>
                    <li><a href="#" draggable="true" class="item-style-2">ITEM_2</a></li>
                    <li><a href="#" draggable="true" class="item-style-3">ITEM_3</a></li>
                    <li><a href="#" draggable="true" class="item-style-4">ITEM_4</a></li>
                </ul>
            </aside>
            <!-- 드롭 영역 -->
            <article class="board"></article>
        </section>
        <footer></footer>
    </main>
</div>

🎯 드래그 앤 드롭 이벤트 적용

드래그 가능한 요소를 만들고, 드롭할 수 있는 .board 영역을 설정하는 과정

🔹 드래그 이벤트 코드

// 🟢 드래그 가능한 요소 가져오기
const liEls = document.querySelectorAll('.items li');
let dragedNode = null;

// 🟢 드래그 시작 시 어떤 요소를 드래그했는지 저장
liEls.forEach((liEl) => {
    liEl.addEventListener('dragstart', (e) => {
        dragedNode = e.target;
    });
});

// 🟢 드롭할 수 있는 영역 설정
const boardEl = document.querySelector('.board');

// 🟢 드롭이 가능하도록 기본 동작 방지
boardEl.addEventListener('dragover', (e) => {
    e.preventDefault();
});

// 🟢 요소를 드롭하면 새로운 요소를 추가
boardEl.addEventListener('drop', (e) => {
    e.preventDefault();
    const newDivEl = document.createElement('div');
    newDivEl.classList.add('item');

    // 드롭된 위치 설정
    newDivEl.setAttribute('style', `left:${e.offsetX}px; top:${e.offsetY}px;`);

    // 기존 요소의 클래스를 새 요소에 적용
    const itemAllClassArr = Object.values(dragedNode.classList);
    itemAllClassArr.forEach((className) => {
        newDivEl.classList.add(className);
    });

    // 요소 이동 기능 추가
    newDivEl.addEventListener('mousedown', movingHandler);

    boardEl.appendChild(newDivEl);
});

🔄 드롭한 요소를 우클릭으로 이동시키기

드롭한 요소를 우클릭하면 이동할 수 있도록 구현

🔹 요소 이동 코드

let isMoving = false;
let targetNode = null;

// 🟢 우클릭하면 이동 시작/종료
const movingHandler = (e) => {
    if (e.button === 2) { // 우클릭
        if (!isMoving) {
            isMoving = true;
            targetNode = e.target;
            targetNode.style.opacity = "0.6"; // 이동 중이면 투명도 조정
            boardEl.addEventListener('mousemove', mouseXYsaveHandler);
        } else {
            isMoving = false;
            targetNode.style.opacity = "1"; // 이동 종료 시 원래 상태로 복구
            targetNode = null;
            boardEl.removeEventListener('mousemove', mouseXYsaveHandler);
        }
    }
};

// 🟢 마우스 위치에 따라 요소 이동
const mouseXYsaveHandler = (e) => {
    if (targetNode) {
        targetNode.style.left = `${e.clientX - 200}px`;
        targetNode.style.top = `${e.clientY}px`;
    }
};

🔗 참고 자료

💡 느낀 점

  • 드래그 앤 드롭 이벤트의 원리를 이해함
  • 우클릭을 활용해 드롭한 요소를 이동하는 기능을 구현함
  • 이벤트 리스너를 동적으로 추가/제거하는 방법을 실습함
  • 추후 개선점: 드래그된 요소의 위치를 로컬스토리지에 저장하여, 새로고침해도 유지될 수 있도록 개선할 예정

📌 요약

학습 주제설명
드래그 앤 드롭 이벤트dragstart, drop, dragover 등 주요 이벤트 학습
파일 업로드이미지 파일만 허용 및 1MB 크기 제한
레이아웃 구성aside, article을 포함한 기본 구조 학습
UI 개선드래그한 요소를 .board 영역에 배치
요소 이동 기능우클릭 시 이동 활성화/비활성화, mousemove 활용
profile
Here, My Pale Blue.🌏

0개의 댓글