DataTransfer API を使用して障壁を取り払う

ユーザーがブラウザ ウィンドウの外でデータを共有できるようにする。

ご存じの方もいらっしゃるかもしれませんが、 DataTransfer API: HTML5 Drag and Drop 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 タイプが 見てみましょう。

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();
});

次の 3 つの MIME タイプがアプリで広くサポートされています。

  • text/html: HTML ペイロードを contentEditable 要素でレンダリングし、リッチにします。 テキスト エディタ(WYSIWYG)を使用できます。
  • text/plain: 入力要素の値、コードエディタのコンテンツ、フォールバックを設定します。 text/html~。
  • text/uri-list: URL バーまたはブラウザページにドロップすると、その URL に移動します。URL ディレクトリやデスクトップにドロップすると、ショートカットが作成されます。

WYSIWYG エディタでは text/html が広く採用されているため、非常に便利です。HTML リソースを埋め込むことができます。 データの URL または一般公開 できます。これは、キャンバスなどのビジュアルを Google ドキュメント

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(リンクデータ)標準は最適な候補です。内容 JavaScript での読み書きが容易です。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 タイプ、 または、より近いユースケース(イベント人物MediaObjectPlace、さらに高度なタイプ( MedicalEntity(必要に応じて)。TypeScript を使用する場合は、 インターフェース定義を schema-dts タイプ定義から取得できます。

JSON-LD データを送受信することで、よりつながりのあるオープンなウェブを実現できます。あり 複数のアプリケーションが同じ言語で動作するようにする場合は、外部との緊密な 説明します。複雑な API 統合は必要ありません必要な情報がすべて 含まれるようになります。

データ共有を必要としない(ウェブ)アプリケーション間でのデータ転送について 制限: カレンダーからお気に入りの ToDo アプリへのイベントの共有、仮想ファイルの添付 メール、連絡先の共有などに使用できます。そうだといいけど。まずはあなたから。🙌

懸念事項

DataTransfer API はすでにご利用いただけますが、統合前に注意すべき点がいくつかあります。

ブラウザの互換性

上記の手法は、パソコンのブラウザはすべて適切にサポートされていますが、モバイル デバイスはサポートされています。 できません。この手法は、すべての主要なブラウザ(Chrome、Edge、Firefox、Safari)でテストされています。 オペレーティング システム(Android、ChromeOS、iOS、macOS、Ubuntu Linux、Windows)にインストールできますが、 テストに合格しませんでしたブラウザは発展を続けているが、現時点ではこの手法は限られている パソコンのブラウザにのみ配信されます

見つけやすさ

ドラッグ ドロップとコピーと貼り付けは、デスクトップ パソコンで作業する際のシステムレベルの操作であり、 40 年以上前の最初の GUI に遡ります自分が何回プレイしたかを ファイルを整理するために、これらの操作を使用しました。これは、ウェブではあまり一般的ではありません。

この新しいインタラクションについてユーザーに説明し、これを行うための UX パターンを考案する必要があります。 特に、これまでのパソコンの使用経験がモバイル デバイスに限られていた人々にとっては、認識しやすいでしょう。

ユーザー補助

ドラッグ&ドロップは使いやすい操作ではありませんが、DataTransfer API はコピー&ペーストにも対応しています。 コピー&ペースト イベントをリッスンするようにしてください。余分な作業はそれほど多くなく、ユーザーは 追加してくれてありがとう

セキュリティとプライバシー

この手法を使用する際には、セキュリティとプライバシーに関するいくつかの点に注意する必要があります。

  • クリップボードのデータは、ユーザーのデバイス上の他のアプリで利用できます。
  • ドラッグしているウェブ アプリケーションは、データではなくタイプキーにアクセスできます。データのみ ドロップまたは貼り付けで使用できます
  • 受信したデータは、他のユーザー入力と同様に扱う必要があります。使用前にサニタイズと検証を行います

Transmat ヘルパー ライブラリのスタートガイド

アプリケーションで DataTransfer API を使うことに興味はありますか。詳しくは、 GitHub の Transmat ライブラリ。このオープンソースライブラリは 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 スプラッシュを解除