끌어서 놓기 기능은 일반적인 기능입니다. 사용자가 원하는 위치에 개체를 잡고 놓을 수 있도록 하여 보다 직관적인 사용자 흐름을 만듭니다. 이 목적을 위해 수많은 JavaScript 라이브러리가 있습니다. 가능한 모든 프레임 워크에 대해 하나를 포함합니다. 그러나 이는 기본 Drag and Drop API를 사용하여 매우 간단하게 수행 할 수 있습니다. 이것이 우리가 살펴볼 것입니다.
이 자습서의 끝에서 Kanban 보드에 대해 다음과 같은 끌어서 놓기 기능을 만드는 방법을 배웁니다.
DOM 설정
먼저 DOM을 설정해 보겠습니다. 프로젝트의 루트 폴더에 index.html 파일을 만들고 다음을 추가합니다.
<main class="board">
<div class="column column-todo">
<h2>Todo</h2>
<article class="card">
<h3>Todo #1</h3>
</article>
<article class="card">
<h3>Todo #2</h3>
</article>
<article class="card">
<h3>Todo #3</h3>
</article>
</div>
<div class="column column-ip">...</div>
<div class="column column-done">...</div>
</main>
<script src="drag-n-drop.js"></script>
다른 두 열인 "In Progress"및 "Done"에 대해서도 동일한 구조가 적용됩니다. 보시다시피 본문 끝에 drag-n-drop.js가 드래그 앤 드롭 기능을 처리합니다.
드래그 앤 드롭 속성 추가
그러나 드래그 앤 드롭으로 작업하려면 먼저 추가 속성으로 DOM 트리를 장식해야 합니다.
<div class="column column-todo" ondrop="drop(event)" ondragover="allowDrop(event)">
<h2>Todo</h2>
<article class="card" draggable="true" ondragstart="drag(event)" data-id="1">
<h3>Todo #1</h3>
</article>
<article class="card" draggable="true" ondragstart="drag(event)" data-id="2">
<h3>Todo #2</h3>
</article>
<article class="card" draggable="true" ondragstart="drag(event)" data-id="3">
<h3>Todo #3</h3>
</article>
</div>
다른 두 열은 정확히 동일한 속성을 갖게 됩니다. 데이터 ID를 제외하고. 각 기사마다 고유 한 ID가 필요합니다. 이것이 JavaScript에서 후크로 사용됩니다. 각 속성의 기능을 살펴 보겠습니다.
이 단계에서 이제 요소를 드래그 할 수 있습니다. 일부 CSS의 도움으로 항목을 잡을 때마다 다른 커서 아이콘을 표시하도록 설정할 수 있습니다.
.card {
cursor: grab;
}
.card:active {
cursor: grabbing;
}
효과를 얻으려면 요소가 활성 상태 일 때만 커서 속성을 변경하면 됩니다.
요소 끌기
이제 모든 설정이 완료되었으므로 요소 드래그 기능 작성을 시작할 수 있습니다. 첫째, 작업에 대해 사용자에게 항상 시각적 인 피드백을 제공해야 합니다. 사용자가 항목을 드래그 할 때 이를 표시하려고 합니다.
요소를 이동하고 싶을 때 요소에 추가 클래스를 추가하여 이 작업을 수행 할 수 있습니다. 이를 위해 drag-n-drop.js에 다음 함수를 추가합니다.
const dragStart = event => {
event.currentTarget.classList.add('dragging');
};
const dragEnd = event => {
event.currentTarget.classList.remove('dragging');
};
document.querySelectorAll('.card').forEach(card => {
card.addEventListener('dragstart', dragStart);
card.addEventListener('dragend', dragEnd);
});
HTML과 달리 여기서는 이벤트 리스너 이름에서 "on"단어를 생략해야 합니다.
이렇게 하면 각 카드에 두 개의 이벤트 리스너가 추가됩니다. 배열 메서드를 사용하려면 querySelectorAll에서 가져온 NodeList를 배열로 변환해야 할 수 있습니다. 글을 쓰는 시점에서 지원은 약 93 %입니다. 그리고 이러한 이벤트는 무엇을 합니까?
항목을 드래그 할 때마다 드래그 클래스가 적용됩니다.
dragging 클래스는 카드에 어떤 역할을 합니까? 불투명도와 비율을 80 %로 설정합니다.
.card {
transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}
.card.dragging {
opacity: .5;
transform: scale(.8);
}
애니메이션을 부드럽게 만들려면 전환 속성을 추가하는 것이 중요합니다.
드래그 앤 드롭이 작동하는 이유는 무엇인가요?
여기에서 모든 dragstart 이벤트에서 실행되는 드래그 기능도 설정해 보겠습니다. 이 함수의 유일한 책임은 항목이 삭제 될 때 나중에 사용할 수 있는 일부 데이터를 설정하는 것입니다.
const drag = event => {
event.dataTransfer.setData('text/html', event.currentTarget.outerHTML);
event.dataTransfer.setData('text/plain', event.currentTarget.dataset.id);
};
dataTransfer 객체는 드래그 된 객체에 대한 데이터를 보유 할 수 있습니다. setData 메소드는 MIME 유형과 페이로드라는 두 가지 매개 변수를 사용합니다. 여기에서 드래그 한 요소의 HTML 콘텐츠와 해당 ID를 저장하려고 합니다. 일을 작동 시키기 위해 우리는 다음을 원합니다.
Dropping Elements
이제 우리는 아이템을 떨어 뜨릴 수 있습니다. 다시 한 번, 사용자가 카드를 열 위로 드래그 할 때 시각적 단서를 추가하여 먼저 시작하겠습니다.
const dragEnter = event => {
event.currentTarget.classList.add('drop');
};
const dragLeave = event => {
event.currentTarget.classList.remove('drop');
};
document.querySelectorAll('.column').forEach(column => {
column.addEventListener('dragenter', dragEnter);
column.addEventListener('dragleave', dragLeave);
});
이번에는 dragenter 및 dragleave 이벤트를 사용하려고 합니다. dragstart 및 dragend와 매우 유사하지만 용도가 다릅니다.
항목을 열 위로 드래그 하면 파선 테두리로 강조 표시됩니다.
CSS 측에서 전환을 다시 설정하고 점선 테두리를 추가해야 합니다.
.column {
transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
}
.column.drop {
border: 2px dashed #FFF;
}
.column.drop article {
pointer-events: none;
}
또 다른 중요한 것은 카드에서 포인터 이벤트를 제거하는 것입니다. 이렇게 하면 카드를 다른 카드 위로 드래그 하더라도 열이 모든 이벤트를 수신하고 점선 테두리를 얻을 수 있습니다.
이제 남은 일은 실제로 새 열에 항목을 추가하는 것입니다. 이를 위해서는 두 가지 추가 기능이 필요합니다.
const drop = event => {
document.querySelectorAll('.column').forEach(column => column.classList.remove('drop'));
document.querySelector(`[data-id="${event.dataTransfer.getData('text/plain')}"]`).remove();
event.currentTarget.innerHTML = event.currentTarget.innerHTML + event.dataTransfer.getData('text/html');
};
const allowDrop = event => {
event.preventDefault();
};
allowDrop 함수는 브라우저의 기본 동작을 방지하는 데 사용되므로 실제로 항목을 열에 놓을 수 있습니다.
드롭 함수에서 먼저 모든 곳에서 드롭 클래스를 제거하려고 합니다 (점선 테두리를 담당 함). 그런 다음 dataTransfer.setData로 설정 한 데이터를 사용할 수 있습니다. 순서대로 :
요약
그리고 그게 다야! 드래그 앤 드롭 기능이 있는 첫 번째 Kanban 보드를 방금 만들었습니다. 네이티브 드래그 앤 드롭 API에 대해 자세히 알아 보려면 MDN 웹 문서의 공식 문서를 확인하세요. 여기에는 끌어서 놓기 수명주기의 여러 단계에서 사용할 수 있는 사용 가능한 모든 끌기 이벤트가 포함됩니다.
완성 된 제품을 가지고 놀고 싶다면 이 GitHub 저장소에서 복제 할 수 있습니다. 이전에 Drag and Drop API를 사용한 적이 있습니까? 아래 댓글에 귀하의 생각을 알려주십시오! 이 기사를 읽어 주셔서 감사합니다. 즐거운 코딩 되세요!
https://www.webtips.dev/how-to-create-native-drag-and-drop-functionality-in-javascript
등록된 댓글이 없습니다.