DataTransfer API를 사용한 장벽 해소

사용자가 브라우저 창 밖에서 데이터를 공유할 수 있도록 합니다.

여러분은 아마도 DataTransfer API는 일부 HTML5 드래그 앤 드롭 API 클립보드 이벤트가 있습니다. 가능 소스와 수신 대상 간에 데이터를 전송하는 데 사용됩니다.

브라우저 지원

  • Chrome: 3. <ph type="x-smartling-placeholder">
  • Edge: 12. <ph type="x-smartling-placeholder">
  • Firefox: 3.5 <ph type="x-smartling-placeholder">
  • Safari: 4. <ph type="x-smartling-placeholder">

소스

페이지 내 상호작용에 자주 사용되는 드래그-드롭 및 복사-붙여넣기 상호작용 A에서 B로 간단한 텍스트를 전송할 수 있습니다. 그러나 종종 간과되는 것은 브라우저 창을 넘을 수 있습니다.

브라우저에 내장된 드래그 앤 드롭과 복사-붙여넣기 상호 작용 모두 출처에 종속되지 않고 다른 애플리케이션과 연결되어 있는 것을 의미합니다 API는 다양한 데이터가 전송되는 위치에 따라 동작을 다르게 하는 데이터 항목을 생성할 수 있습니다. 내 웹 애플리케이션은 수신되는 이벤트를 수신 대기할 때 전송된 데이터를 주고받을 수 있습니다.

이 기능은 웹에서의 공유 및 상호 운용성에 대한 생각을 바꿀 수 있습니다. 애플리케이션을 실행할 수 있습니다 애플리케이션 간 데이터 전송 시에는 더 이상 긴밀하게 결합된 통합을 지원하지 않습니다. 대신 사용자에게 이전을 위한 전체 제어 권한을 부여할 수 있습니다. 어디에나 데이터를 배포할 수 있습니다

<ph type="x-smartling-placeholder">
</ph>
DataTransfer API로 가능한 상호작용의 예입니다. (동영상에는 사운드가 포함되지 않습니다.)

데이터 전송

시작하려면 드래그-드롭 또는 복사-붙여넣기를 구현해야 합니다. 예시 드래그 드롭 상호작용을 보여주지만 복사하여 붙여넣기 프로세스는 비슷합니다. 만약 Drag and Drop API에 익숙하지 않으시다면 자세한 내용은 HTML5 드래그 앤 드롭 설명을 참조하세요.

MIME 유형 키 데이터를 제공하면 외부 애플리케이션과 자유롭게 상호작용할 수 있습니다. 대부분의 WYSIWYG 편집기, 텍스트 편집기 및 브라우저는 '프리미티브' mime-type이 참조하세요.

document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
  event.dataTransfer.setData('text/plain', 'Foo bar');
  event.dataTransfer.setData('text/html', '<h1>Foo bar</h1>');
  event.dataTransfer.setData('text/uri-list', 'https://example.com');
});

event.dataTransfer 속성을 확인합니다. 이 메서드는 DataTransfer 따라서 이 객체는 이름이 다른 속성에 의해 반환되는 경우가 있습니다.

데이터 전송을 수신하는 방법은 데이터 전송을 제공하는 것과 거의 동일합니다. 수신 이벤트 수신 대기 (drop 또는 paste)하고 키를 읽습니다. 요소 위로 드래그할 때 브라우저에서는 데이터의 type 키에 연결합니다. 데이터 자체는 삭제 후에만 액세스할 수 있습니다.

document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
  console.log(event.dataTransfer.types);
  // Without this, the drop event won't fire.
  event.preventDefault();
});

document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
  // Log all the transferred data items to the console.
  for (let type of event.dataTransfer.types) {
    console.log({ type, data: event.dataTransfer.getData(type) });
  }
  event.preventDefault();
});

세 가지 MIME 유형이 애플리케이션 전반에 걸쳐 널리 지원됩니다.

  • text/html: HTML 페이로드를 contentEditable 요소 및 리치로 렌더링합니다. Google Docs, Microsoft Word와 같은 텍스트 (WYSIWYG) 편집기
  • text/plain: 입력 요소, 코드 편집기의 콘텐츠, 대체 값을 설정합니다. 최저가 text/html.
  • text/uri-list: URL 표시줄 또는 브라우저 페이지에 드롭하면 URL로 이동합니다. URL 바로가기가 디렉터리나 바탕화면에 드롭하면 만들어집니다.

WYSIWYG 편집자는 text/html를 광범위하게 채택하여 매우 유용합니다. HTML에서와 같이 을 사용하여 리소스를 삽입할 수 있습니다. 데이터 URL 또는 공개 액세스할 수 있습니다. 이 기능은 시각 자료 (예: 캔버스에서)를 Google Docs도구.

const redPixel = 'data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=';
const html = '<img src="' + redPixel + '" width="100" height="100" alt="" />';
event.dataTransfer.setData('text/html', html);

복사하여 붙여넣기를 사용하여 전송

복사-붙여넣기 상호작용과 함께 DataTransfer API를 사용하는 방법은 다음과 같습니다. 주목하세요. DataTransfer 객체는 클립보드 이벤트의 경우 clipboardData라는 속성에 의해 반환됩니다.

// Listen to copy-paste events on the document.
document.addEventListener('copy', (event) => {
  const copySource = document.querySelector('#copySource');
  // Only copy when the `activeElement` (i.e., focused element) is,
  // or is within, the `copySource` element.
  if (copySource.contains(document.activeElement)) {
    event.clipboardData.setData('text/plain', 'Foo bar');
    event.preventDefault();
  }
});

document.addEventListener('paste', (event) => {
  const pasteTarget = document.querySelector('#pasteTarget');
  if (pasteTarget.contains(document.activeElement)) {
    const data = event.clipboardData.getData('text/plain');
    console.log(data);
  }
});

맞춤 데이터 형식

기본 MIME 유형으로 제한되지 않지만 모든 키를 사용하여 전송된 MIME 유형을 식별할 수 있습니다. 데이터를 수집하는 데 사용됩니다 이는 애플리케이션 내에서 브라우저 간 상호작용에 유용할 수 있습니다. 아래와 같이 JSON.stringify()JSON.parse() 함수를 사용하여 더 복잡한 데이터를 전송할 수 있습니다.

document.querySelector('#dragSource')
.addEventListener('dragstart', (event) => {
  const data = { foo: 'bar' };
  event.dataTransfer.setData('my-custom-type', JSON.stringify(data));
});

document.querySelector('#dropTarget')
.addEventListener('dragover', (event) => {
  // Only allow dropping when our custom data is available.
  if (event.dataTransfer.types.includes('my-custom-type')) {
    event.preventDefault();
  }
});

document.querySelector('#dropTarget')
.addEventListener('drop', (event) => {
  if (event.dataTransfer.types.includes('my-custom-type')) {
    event.preventDefault();
    const dataString = event.dataTransfer.getData('my-custom-type');
    const data = JSON.parse(dataString);
    console.log(data);
  }
});

웹 연결

맞춤 형식은 사용자가 제어할 수 있는 애플리케이션 간의 커뮤니케이션에 효과적이지만 해당 형식을 사용하지 않는 애플리케이션으로 데이터를 전송할 때도 사용자를 제한합니다. 원하는 경우 웹에서 서드 파티 애플리케이션과 연결하려면 범용 데이터 형식이 필요합니다.

JSON-LD (연결된 데이터) 표준이 이를 위한 적합한 후보입니다. 그것은 가볍고 자바스크립트에서 읽고 쓰기가 쉽습니다. Schema.org에는 사용할 수 있는 사전 정의된 유형으로 구성되며, 커스텀 스키마 정의도 옵션입니다.

const data = {
  '@context': 'https://schema.org',
  '@type': 'ImageObject',
  contentLocation: 'Venice, Italy',
  contentUrl: 'venice.jpg',
  datePublished: '2010-08-08',
  description: 'I took this picture during our honey moon.',
  name: 'Canal in Venice',
};
event.dataTransfer.setData('application/ld+json', JSON.stringify(data));

Schema.org 유형을 사용할 때는 일반적인 Thing 유형으로 시작할 수 있습니다. 또는 Event, Person, MediaObject, Place 또는 매우 구체적인 유형(예: 필요한 경우 MedicalEntity TypeScript를 사용할 때는 schema-dts 유형 정의에서 가져온 인터페이스 정의를 사용합니다.

JSON-LD 데이터를 송수신함으로써 더욱 연결된 개방형 웹을 지원할 수 있습니다. 다음으로 바꿉니다. 같은 언어를 사용하는 애플리케이션을 빌드하려는 경우 외부 리소스 및 애플리케이션을 실행할 수 있습니다 복잡한 API 통합이 필요하지 않습니다. 필요한 모든 정보가 전송되는 데이터에 포함됩니다.

모든 (웹) 애플리케이션 간에 데이터를 전송할 수 있는 모든 가능성을 제한사항: 캘린더의 일정을 즐겨찾는 할 일 앱으로 공유하거나 가상 파일을 첨부할 때 이메일, 연락처 공유 등입니다. 그게 좋겠지? 여러분과 함께 시작합니다. 🙌

문제

DataTransfer API는 현재 사용할 수 있지만 통합하기 전에 알아야 할 몇 가지 사항이 있습니다.

브라우저 호환성

데스크톱 브라우저는 모두 위에서 설명한 기술을 잘 지원하는 반면 모바일 장치는 아닙니다. 이 기술은 모든 주요 브라우저 (Chrome, Edge, Firefox, Safari)에서 테스트되었으며 운영체제 (Android, ChromeOS, iOS, macOS, Ubuntu Linux, Windows)를 지원하지만 Android는 iOS는 테스트를 통과하지 못했습니다 브라우저는 계속 개발되고 있지만 현재로서는 이 기술이 제한적입니다. 데스크톱 브라우저에서만 사용할 수 있습니다.

발견 가능성

드래그-드롭과 복사하여 붙여넣기는 데스크톱 컴퓨터에서 작업할 때 시스템 수준의 상호작용이며 40여 년 전 최초의 GUI에 뿌리를 두고 있습니다. 당신이 얼마나 많은 일을 했는지 생각해 보세요 이러한 상호작용을 사용하여 파일을 구성했습니다. 이러한 방식은 웹에서는 아직 흔하지 않습니다.

사용자에게 새로운 상호작용에 대해 교육하고 이를 위해 UX 패턴을 제시해야 합니다. 특히 지금까지 컴퓨터 사용 경험이 모바일 기기에 국한된 사람에게는 더욱 그렇습니다.

접근성

드래그-드롭은 접근성이 좋은 상호작용은 아니지만, DataTransfer API는 복사-붙여넣기 기능도 지원합니다. 복사하여 붙여넣기 이벤트를 수신 대기해야 합니다. 추가 작업이 필요하지 않으며 추가해 주셔서 감사합니다.

보안 및 개인 정보 보호

이 기술을 사용할 때 알아야 할 몇 가지 보안 및 개인 정보 보호 고려사항이 있습니다.

  • 클립보드 데이터는 사용자 기기의 다른 애플리케이션에서 사용할 수 있습니다.
  • 드래그 중인 웹 애플리케이션은 데이터가 아닌 유형 키에 액세스할 수 있습니다. 데이터만 드롭 또는 붙여넣기에서 사용할 수 있습니다.
  • 수신된 데이터는 다른 사용자 입력과 마찬가지로 취급되어야 합니다. 정리 및 검증을 거쳐야 합니다

Transmat 도우미 라이브러리 시작하기

애플리케이션에서 DataTransfer API를 사용하는 데 관심이 있나요? 먼저 GitHub의 변환 라이브러리 이 오픈소스 라이브러리는 JSON-LD 유틸리티를 제공하며, 대상의 전송 이벤트에 응답하는 관찰자가 포함되어 있습니다. 드롭 영역을 강조표시하여 기존 드래그 앤 드롭 간의 데이터 전송 작업을 통합할 수 있습니다. 있습니다.

import { Transmat, TransmatObserver, addListeners } from 'transmat';

// Send data on drag/copy.
addListeners(myElement, 'transmit', (event) => {
  const transmat = new Transmat(event);
  transmat.setData({
    'text/plain': 'Foobar',
    'application/json': { foo: 'bar' },
  });
});

// Receive data on drop/paste.
addListeners(myElement, 'receive', (event) => {
  const transmat = new Transmat(event);
  if (transmat.hasType('application/json') && transmat.accept()) {
    const data = JSON.parse(transmat.getData('application/json'));
  }
});

// Observe transfer events and highlight drop areas.
const obs = new TransmatObserver((entries) => {
  for (const entry of entries) {
    const transmat = new Transmat(entry.event);
    if (transmat.hasMimeType('application/json')) {
      entry.target.classList.toggle('drag-over', entry.isTarget);
      entry.target.classList.toggle('drag-active', entry.isActive);
    }
  }
});
obs.observe(myElement);

감사의 말씀

Luba Ertel 제공 히어로 이미지 스플래시 해제.