HTML5 드래그 앤 드롭 API

이 게시물에서는 드래그 앤 드롭의 기본사항을 설명합니다.

드래그 가능한 콘텐츠 만들기

대부분의 브라우저에서는 기본적으로 텍스트 선택, 이미지 및 링크를 드래그할 수 있습니다. 예를 들어 웹페이지에서 링크를 드래그하면 주소 표시줄이나 바탕화면에 드롭할 수 있는 제목과 URL 바로가기를 클릭하거나 링크로 이동하세요. 다른 유형의 콘텐츠를 드래그 가능하게 만들려면 HTML5 드래그 앤 드롭 API를 사용해야 합니다.

객체를 드래그 가능하도록 만들려면 요소에 draggable=true를 설정합니다. 거의 이미지, 파일, 링크, 파일 또는 페이지에 마크업을 추가해야 합니다.

다음 예에서는 2012년 4월 24일 이전에 CSS 그리드로 배치되어 있습니다. 열에 대한 기본 마크업은 다음과 같습니다. 각 열의 draggable 속성을 true로 설정합니다.

<div class="container">
  <div draggable="true" class="box">A</div>
  <div draggable="true" class="box">B</div>
  <div draggable="true" class="box">C</div>
</div>

다음은 컨테이너 및 상자 요소의 CSS입니다. 이 광고 항목과 관련된 유일한 CSS는 드래그 기능은 cursor: move입니다. 속성 코드의 나머지 부분은 컨테이너의 레이아웃과 스타일을 제어합니다. 상자 요소가 있습니다.

.container {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}

.box {
  border: 3px solid #666;
  background-color: #ddd;
  border-radius: .5em;
  padding: 10px;
  cursor: move;
}

이 시점에서 항목을 드래그할 수 있지만 아무것도 되지 않습니다. 추가 JavaScript API를 사용해야 합니다.

드래그 이벤트 수신 대기

드래그 프로세스를 모니터링하려면 다음 이벤트를 수신 대기하면 됩니다.

드래그 흐름을 처리하려면 일종의 소스 요소 (여기서 드래그 데이터 페이로드 (드래그되는 항목), 대상 (대상) 드롭을 포착합니다). 소스 요소는 거의 모든 종류의 요소가 될 수 있습니다. 이 target은 사용자가 있는 데이터를 허용하는 드롭 영역 또는 드롭 영역 집합입니다. 있습니다. 모든 요소가 타겟이 될 수 있는 것은 아닙니다. 예를 들어 타겟은 이미지일 수 있습니다.

드래그 시퀀스 시작 및 종료

콘텐츠에 draggable="true" 속성을 정의한 후 각 열의 드래그 시퀀스를 시작하는 dragstart 이벤트 핸들러입니다.

이 코드는 사용자가 열을 드래그하기 시작할 때 열의 불투명도를 40% 로 설정합니다. 드래그 이벤트가 종료되면 100% 로 되돌립니다.

function handleDragStart(e) {
  this.style.opacity = '0.4';
}

function handleDragEnd(e) {
  this.style.opacity = '1';
}

let items = document.querySelectorAll('.container .box');
items.forEach(function (item) {
  item.addEventListener('dragstart', handleDragStart);
  item.addEventListener('dragend', handleDragEnd);
});

결과는 다음 Glitch 데모에서 확인할 수 있습니다. 항목을 드래그하고 변경할 수 있습니다. 소스 요소에 dragstart 이벤트가 있으므로 this.style.opacity~40% 는 사용자에게 요소가 다음과 같은 시각적 반응을 제공합니다. 이동 중인 현재 선택 영역을 나타냅니다. 항목을 드롭하면 소스 요소가 100% 불투명도로 돌아갑니다. 이는 아직 드롭 동작을 정의하지 않은 경우에도 마찬가지입니다.

시각적 신호 추가

사용자가 인터페이스와 상호작용하는 방법을 이해하도록 하려면 dragenter, dragover, dragleave 이벤트 핸들러 이 예에서 열은 드래그할 수 있을 뿐만 아니라 드롭 타겟입니다. 사용자가 다음 작업을 할 수 있도록 지원 드래그한 항목을 지도 위에 놓을 때 테두리를 파선으로 만들어 이를 이해할 수 있습니다. 를 클릭합니다. 예를 들어 CSS에서 다음을 위한 over 클래스를 만들 수 있습니다. 드롭 타겟 요소:

.box.over {
  border: 3px dotted #666;
}

그런 다음 JavaScript에서 이벤트 핸들러를 설정하고, 다음과 같은 경우 over 클래스를 추가합니다. 열을 드래그하고 드래그한 요소가 나가면 열을 삭제합니다. 포함 dragend 핸들러도 있는데, 드래그

document.addEventListener('DOMContentLoaded', (event) => {

  function handleDragStart(e) {
    this.style.opacity = '0.4';
  }

  function handleDragEnd(e) {
    this.style.opacity = '1';

    items.forEach(function (item) {
      item.classList.remove('over');
    });
  }

  function handleDragOver(e) {
    e.preventDefault();
    return false;
  }

  function handleDragEnter(e) {
    this.classList.add('over');
  }

  function handleDragLeave(e) {
    this.classList.remove('over');
  }

  let items = document.querySelectorAll('.container .box');
  items.forEach(function(item) {
    item.addEventListener('dragstart', handleDragStart);
    item.addEventListener('dragover', handleDragOver);
    item.addEventListener('dragenter', handleDragEnter);
    item.addEventListener('dragleave', handleDragLeave);
    item.addEventListener('dragend', handleDragEnd);
    item.addEventListener('drop', handleDrop);
  });
});

이 코드에서는 몇 가지 중요한 사항을 다룹니다.

  • 기본 작업 dragover 이벤트의 경우 dataTransfer.dropEffect 속성을 다음과 같이 설정합니다. "none"입니다. dropEffect 속성은 이 페이지의 뒷부분에서 다룹니다. 지금은 drop 이벤트가 실행되지 않는다는 것만 알아두세요. 이 값을 재정의하려면 e.preventDefault()를 호출합니다. 또 다른 좋은 방법은 false를 호출합니다.

  • dragenter 이벤트 핸들러는 over 클래스를 전환하는 데 사용됩니다. dragover입니다. dragover를 사용하면 사용자가 드래그한 항목을 열 위에 유지하여 CSS 클래스가 전환되도록 합니다. 합니다. 따라서 브라우저가 불필요하게 렌더링 작업을 많이 하게 되고 사용자 환경에 영향을 미칠 수 있습니다. Google에서는 다시 그리고 dragover를 사용해야 하는 경우 이벤트 리스너 제한 또는 디바운싱

출시 완료

드롭을 처리하려면 drop 이벤트의 이벤트 리스너를 추가합니다. drop에 있음 핸들러에서 드롭하는 경우, 드롭에 대한 브라우저의 기본 동작을 방지해야 합니다. 일반적으로 성가신 리디렉션입니다. 이렇게 하려면 e.stopPropagation()를 호출합니다.

function handleDrop(e) {
  e.stopPropagation(); // stops the browser from redirecting.
  return false;
}

새 핸들러를 다른 핸들러와 함께 등록해야 합니다.

  let items = document.querySelectorAll('.container .box');
  items.forEach(function(item) {
    item.addEventListener('dragstart', handleDragStart);
    item.addEventListener('dragover', handleDragOver);
    item.addEventListener('dragenter', handleDragEnter);
    item.addEventListener('dragleave', handleDragLeave);
    item.addEventListener('dragend', handleDragEnd);
    item.addEventListener('drop', handleDrop);
  });

이 시점에서 코드를 실행하면 항목이 새 위치에 드롭되지 않습니다. 받는사람 이렇게 하려면 DataTransfer 객체를 지정합니다.

dataTransfer 속성에는 드래그 작업에서 전송된 데이터가 저장됩니다. dataTransfer dragstart 이벤트에서 설정되고 드롭 이벤트에서 읽거나 처리됩니다. 전화 거는 중 e.dataTransfer.setData(mimeType, dataPayload)를 사용하면 객체의 MIME를 설정할 수 있습니다. 유형 및 데이터 페이로드가 있습니다

이 예에서는 사용자가 열의 순서를 재정렬할 수 있도록 합니다. 이렇게 하려면 먼저 드래그 앤 드롭할 때 소스 요소의 HTML을 저장해야 합니다. 시작:

function handleDragStart(e) {
  this.style.opacity = '0.4';

  dragSrcEl = this;

  e.dataTransfer.effectAllowed = 'move';
  e.dataTransfer.setData('text/html', this.innerHTML);
}

drop 이벤트에서 소스 열의 데이터를 삭제한 타겟 열의 HTML에 HTML을 추가합니다. 이 사용자가 동일한 열로 돌아가지 않는지 확인하는 것이 포함됩니다. 합니다.

function handleDrop(e) {
  e.stopPropagation();

  if (dragSrcEl !== this) {
    dragSrcEl.innerHTML = this.innerHTML;
    this.innerHTML = e.dataTransfer.getData('text/html');
  }

  return false;
}

다음 데모에서 결과를 확인할 수 있습니다. 이 기능을 사용하려면 사용할 수 있습니다. 드래그 앤 드롭 API는 모바일에서 지원되지 않습니다. 드래그하고 B 열 위에 A 열을 놓고 위치가 어떻게 바뀌는지 확인합니다.

드래그 속성 더보기

dataTransfer 객체는 속성을 노출하여 각 드롭 타겟이 특정 데이터 유형을 가져올 수 있습니다

  • dataTransfer.effectAllowed 드림 '드래그 유형'을 제한하여 사용자가 해당 요소에서 수행할 수 있습니다. 그 것은 드래그 앤 드롭 처리 모델에서 dropEffect를 초기화하도록 설정합니다. dragenterdragover 이벤트 속성은 다음 값: none, copy, copyLink, copyMove, link, linkMove, move, all, uninitialized
  • dataTransfer.dropEffect 드림 dragenterdragover 중에 사용자가 받는 피드백을 제어합니다. 이벤트를 수신합니다. 사용자가 타겟 요소 위에 포인터를 올려놓으면 브라우저의 커서는 실행할 작업의 유형을 나타냅니다(예: 이동할 수도 있습니다 효과는 none, copy, link, move
  • e.dataTransfer.setDragImage(imgElement, x, y) 드림 이는 브라우저의 기본 '고스트 이미지' 대신 피드백을 드래그 아이콘을 설정할 수 있습니다.

파일 업로드

이 간단한 예에서는 열을 드래그 소스와 드래그 대상으로 모두 사용합니다. 이 사용자에게 항목을 재정렬하도록 요청하는 UI에서 발생할 수 있습니다. 어떤 경우에는 드래그 대상과 소스는 인터페이스와 같이 다른 요소 유형일 수 있습니다. 사용자가 제품의 기본 이미지로 하나의 이미지를 선택하고 선택한 이미지를 타겟으로 드래그합니다.

드래그 앤 드롭은 사용자가 데스크톱의 항목을 데스크톱 화면으로 드래그 앤 드롭하는 데 자주 사용됩니다. 실행할 수 있습니다 주요 차이점은 drop 핸들러에 있습니다. kubectl 명령어 dataTransfer.getData()로 파일에 액세스할 수 있으며 이 파일의 데이터는 dataTransfer.files 속성:

function handleDrop(e) {
  e.stopPropagation(); // Stops some browsers from redirecting.
  e.preventDefault();

  var files = e.dataTransfer.files;
  for (var i = 0, f; (f = files[i]); i++) {
    // Read the File objects in this FileList.
  }
}

이에 대한 자세한 내용은 맞춤 드래그 앤 드롭.

추가 리소스