웹사이트 검색

Vanilla JavaScript 및 HTML로 드래그 앤 드롭 요소를 만드는 방법


소개

끌어서 놓기는 많은 그래픽 사용자 인터페이스에서 찾을 수 있는 일반적인 사용자 상호 작용입니다.

앱에 끌어서 놓기 기능을 추가하기 위한 기존 JavaScript 라이브러리가 있습니다. 그러나 라이브러리를 사용할 수 없거나 프로젝트에 필요하지 않은 오버헤드 또는 종속성이 도입되는 상황이 있을 수 있습니다. 이러한 상황에서 최신 웹 브라우저에서 사용할 수 있는 API에 대한 지식은 대체 솔루션을 제공할 수 있습니다.

HTML 드래그 앤 드롭 API는 DOM의 이벤트 모델에 의존하여 드래그 또는 드롭되는 항목에 대한 정보를 얻고 드래그 또는 드롭에서 해당 요소를 업데이트합니다. JavaScript 이벤트 핸들러를 사용하면 모든 요소를 끌어서 놓을 수 있는 항목으로 바꿀 수 있습니다.

이 자습서에서는 이벤트 핸들러를 사용하기 위해 바닐라 JavaScript와 함께 HTML 드래그 앤 드롭 API를 사용하여 드래그 앤 드롭 예제를 빌드합니다.

전제 조건

이 자습서를 완료하려면 다음이 필요합니다.

  • 드래그 앤 드롭 API를 지원하는 최신 웹 브라우저(Chrome 4+, Firefox 3.5+, Safari 3.1+, Edge 18+).

1단계 - 프로젝트 및 초기 마크업 만들기

우리 프로젝트는 두 가지 유형의 하위 요소가 있는 컨테이너로 구성됩니다.

  • 드래그할 수 있는 하위 요소
  • 요소를 드롭할 수 있는 하위 요소

먼저 터미널 창을 열고 새 프로젝트 디렉토리를 만듭니다.

  1. mkdir drag-and-drop-example

그런 다음 해당 디렉터리로 이동합니다.

  1. cd drag-and-drop-example

그런 다음 해당 디렉터리에 index.html 파일을 만듭니다.

  1. nano index.html

다음으로 HTML 웹 페이지에 대한 상용구 코드를 추가합니다.

<!DOCTYPE html>
<html>
  <head>
    <title>My Drag-and-Drop Example</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
  </body>
</html>

그리고 <body> 태그 사이에 draggable 항목과 dropzone을 추가합니다( 드롭 대상):

<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
  >
    dropzone
  </div>
</div>

파일을 저장하고 닫습니다. 그런 다음 style.css 파일을 만듭니다.

  1. nano style.css

다음으로 index.html 파일의 요소에 대한 스타일을 추가합니다.

.example-parent {
  border: 2px solid #DFA612;
  color: black;
  display: flex;
  font-family: sans-serif;
  font-weight: bold;
}

.example-origin {
  flex-basis: 100%;
  flex-grow: 1;
  padding: 10px;
}

.example-draggable {
  background-color: #4AAE9B;
  font-weight: normal;
  margin-bottom: 10px;
  margin-top: 10px;
  padding: 10px;
}

.example-dropzone {
  background-color: #6DB65B;
  flex-basis: 100%;
  flex-grow: 1;
  padding: 10px;
}

이렇게 하면 앱에 서식이 추가됩니다. 이제 브라우저에서 index.html을 볼 수 있으며 이것이 드래그 가능 <div>드롭존 <div>.

다음으로 draggable 속성을 추가하여 명시적으로 첫 번째 <div>를 드래그 가능하게 만듭니다.

<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
  >
    dropzone
  </div>
</div>

파일을 저장하고 닫습니다.

마지막으로 브라우저에서 index.html을 다시 봅니다. 드래그 가능한 <div>를 클릭하고 화면에서 드래그하면 이동하는 시각적 표시가 있어야 합니다.

draggable 속성의 기본값은 auto입니다. 즉, 요소를 드래그할 수 있는지 여부는 브라우저의 기본 동작에 따라 결정됩니다. 일반적으로 이는 draggable=\true\를 지정하지 않고 텍스트 선택, 이미지 및 링크를 드래그할 수 있음을 의미합니다.

이제 끌 수 있는 요소가 있는 HTML 파일이 생겼습니다. onevent 핸들러 추가로 이동하겠습니다.

2단계 — JavaScript로 드래그 앤 드롭 이벤트 처리

현재 드래그 가능한 요소를 드래그하는 동안 마우스를 놓으면 아무 일도 일어나지 않습니다. DOM 요소에서 드래그 또는 드롭에 대한 작업을 트리거하려면 드래그 앤 드롭 API를 활용해야 합니다.

  • ondragstart: 이 이벤트 핸들러는 draggable 요소에 첨부되며 dragstart 이벤트가 발생할 때 실행됩니다. .
  • ondragover: 이 이벤트 핸들러는 dropzone 요소에 연결되고 dragover 이벤트가 발생할 때 실행됩니다. .
  • ondrop: 이 이벤트 핸들러는 dropzone 요소에도 첨부되며 drop 이벤트가 발생할 때 실행됩니다. 발생합니다.

참고: 총 8개의 이벤트 처리기가 있습니다: ondrag, ondragend, ondragenter, ondragexit, ondragleave , ondragover, ondragstartondrop. 이 예에서는 모두 필요하지 않습니다.

먼저 index.html에서 새 script.js 파일을 참조해 보겠습니다.

<body>
  ...
  <script src="script.js"></script>
</body>

다음으로 새 script.js 파일을 만듭니다.

  1. nano script.js

DataTransfer 개체는 현재 발생하는 드래그와 관련된 정보를 추적합니다. 드래그 앤 드롭으로 요소를 업데이트하려면 DataTransfer 개체에 직접 액세스해야 합니다. 이를 위해 DOM 요소의 DragEvent에서 dataTransfer 속성을 선택할 수 있습니다.

참고: DataTransfer 개체는 기술적으로 동시에 드래그되는 여러 요소에 대한 정보를 추적할 수 있습니다. 이 예에서는 하나의 요소를 드래그하는 데 중점을 둘 것입니다.

dataTransfer 개체의 setData 메서드는 현재 드래그된 요소의 드래그 상태 정보를 설정하는 데 사용할 수 있습니다. 다음 두 가지 매개변수를 사용합니다.

  • 두 번째 매개변수의 형식을 선언하는 문자열
  • 전송되는 실제 데이터

우리의 목표는 draggable 요소를 새로운 상위 요소로 옮기는 것입니다. 고유한 id가 있는 드래그 가능한 요소를 선택할 수 있어야 합니다. 나중에 사용할 수 있도록 setData 메서드로 드래그한 요소의 id를 설정할 수 있습니다.

script.js 파일을 다시 방문하여 setData를 사용하는 새 함수를 생성해 보겠습니다.

function onDragStart(event) {
  event
    .dataTransfer
    .setData('text/plain', event.target.id);
}

참고: Internet Explorer 9에서 11까지는 text/plain을 사용하는 데 문제가 있는 것으로 알려졌습니다. 해당 브라우저의 형식은 text여야 합니다.

드래그한 항목의 CSS 스타일을 업데이트하려면 DOM 이벤트를 다시 사용하고 currentTarget에 대해 원하는 스타일을 설정하여 해당 스타일에 액세스할 수 있습니다.

함수에 추가하고 backgroundColor노란색으로 변경해 보겠습니다.

function onDragStart(event) {
  event
    .dataTransfer
    .setData('text/plain', event.target.id);

  event
    .currentTarget
    .style
    .backgroundColor = 'yellow';
}

참고: 드래그 전용 스타일을 원하는 경우 변경한 모든 스타일을 놓을 때 다시 수동으로 업데이트해야 합니다. 드래그를 시작할 때 무엇이든 변경하면 드래그한 요소는 다시 변경하지 않는 한 새 스타일을 유지합니다.

이제 끌기가 시작될 때 JavaScript 기능이 있습니다.

index.htmldraggable 요소에 ondragstart를 추가할 수 있습니다.

<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div class="example-dropzone">
    dropzone
  </div>
</div>

브라우저에서 index.html을 봅니다. 지금 항목을 드래그하려고 하면 함수에 선언된 스타일이 적용됩니다.

그러나 클릭을 해제하면 아무 일도 일어나지 않습니다.

이 시퀀스에서 실행되는 다음 이벤트 핸들러는 ondragover입니다.

브라우저의 <div>와 같은 특정 DOM 요소에 대한 기본 드롭 동작은 일반적으로 드롭을 허용하지 않습니다. 이 동작은 구현하려는 동작을 가로챕니다. 원하는 놓기 동작을 얻기 위해 preventDefault를 적용합니다.

script.js 파일을 다시 방문하여 preventDefault를 사용하는 새 함수를 만들어 봅시다. 파일 끝에 다음 코드를 추가합니다.

function onDragOver(event) {
  event.preventDefault();
}

이제 index.htmldropzone 요소에 ondragover를 추가할 수 있습니다.

<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
  >
    dropzone
  </div>
</div>

이 시점에서 우리는 아직 실제 드롭을 처리하는 코드를 작성하지 않았습니다. 이 시퀀스에서 실행되는 마지막 이벤트 핸들러는 ondrop입니다.

script.js 파일을 다시 방문하여 새 함수를 만들어 봅시다.

dataTransfer 개체의 setData 메서드를 사용하여 이전에 저장한 데이터를 참조할 수 있습니다. dataTransfer 개체의 getData 메서드를 사용합니다. 우리가 설정한 데이터는 id였으므로 그것이 우리에게 반환될 것입니다:

function onDrop(event) {
  const id = event
    .dataTransfer
    .getData('text');
}

검색한 id가 있는 draggable 요소를 선택합니다.

function onDrop(event) {
  // ...

  const draggableElement = document.getElementById(id);
}

dropzone 요소를 선택합니다.

function onDrop(event) {
  // ...

  const dropzone = event.target;
}

draggable 요소를 dropzone에 추가합니다.

function onDrop(event) {
  // ...

  dropzone.appendChild(draggableElement);
}

dataTransfer 개체를 재설정합니다.

function onDrop(event) {
  // ...

  event
    .dataTransfer
    .clearData();
}

이제 index.htmldropzone 요소에 ondrop을 추가할 수 있습니다.

<div class="example-parent">
  <div class="example-origin">
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      draggable
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
    ondrop="onDrop(event);"
  >
    dropzone
  </div>
</div>

완료되면 끌어서 놓기 기능이 완성됩니다. 브라우저에서 index.html을 보고 draggable 요소를 드롭존으로 드래그합니다. .

이 예에서는 드래그할 수 있는 단일 항목과 단일 드롭 대상의 시나리오를 처리합니다. 드래그할 수 있는 여러 항목, 여러 드롭 대상을 가질 수 있으며 다른 모든 드래그 앤 드롭 API 이벤트 핸들러로 사용자 정의할 수 있습니다.

3단계 - 드래그 가능한 여러 항목으로 고급 예제 빌드

다음은 이 API를 사용하는 방법에 대한 또 다른 예입니다. \할 일\ 열에서 \완료\ 로 이동할 수 있는 드래그 가능한 작업이 포함된 할 일 목록 칼럼.

고유한 할 일 목록을 만들려면 고유한 id가 있는 드래그 가능한 요소를 index.html에 추가하세요.

<div class="example-parent">
  <h1>To-do list</h1>
  <div class="example-origin">
    To-do
    <div
      id="draggable-1"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 1
    </div>
    <div
      id="draggable-2"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 2
    </div>
    <div
      id="draggable-3"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 3
    </div>
    <div
      id="draggable-4"
      class="example-draggable"
      draggable="true"
      ondragstart="onDragStart(event);"
    >
      thing 4
    </div>
  </div>

  <div
    class="example-dropzone"
    ondragover="onDragOver(event);"
    ondrop="onDrop(event);"
  >
    Done
  </div>
</div>

브라우저에서 index.html을 보고 To-do 열의 항목을 Done 열로 드래그합니다. 할 일 애플리케이션을 만들고 기능을 테스트했습니다.

결론

이 문서에서는 최신 웹 브라우저에서 사용할 수 있는 끌어서 놓기 기능을 탐색하기 위해 할 일 앱을 만들었습니다.

끌어서 놓기 API는 끌어서 놓기 이외의 작업을 사용자 지정하기 위한 여러 옵션을 제공합니다. 예를 들어 드래그한 항목의 CSS 스타일을 업데이트할 수 있습니다. 또한 항목을 이동하는 대신 드래그할 수 있는 항목을 복사하여 놓을 때 복제되도록 선택할 수 있습니다.

많은 웹 브라우저가 이 기술을 지원하지만 청중이 이 기능을 지원하지 않는 장치로 구성된 경우에는 이 기술을 사용하지 못할 수 있습니다.

Drag and Drop API로 놓을 수 있는 모든 것에 대해 자세히 알아보려면 MDN의 문서를 확인하십시오.