DataTransfer API'yi kullanarak bariyerleri ortadan kaldırma

Kullanıcının verileri tarayıcı penceresinin ötesinde paylaşmasına olanak tanır.

DataTransfer API'yi duymuş olabilirsiniz. Bu API, HTML5 Drag and Drop API ve Clipboard events'in bir parçasıdır. Kaynak ve alıcı hedefler arasında veri aktarmak için kullanılabilir.

Browser Support

  • Chrome: 3.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 4.

Source

Sürükle-bırak ve kopyala-yapıştır etkileşimleri, genellikle bir sayfa içindeki etkileşimlerde A'dan B'ye basit metin aktarmak için kullanılır. Ancak genellikle gözden kaçırılan nokta, bu etkileşimleri tarayıcı penceresinin ötesine geçmek için kullanabilmektir.

Hem tarayıcının yerleşik sürükle ve bırak özelliği hem de kopyalama-yapıştırma etkileşimleri, diğer uygulamalarla (web veya başka) iletişim kurabilir ve herhangi bir kaynağa bağlı değildir. API, verilerin nereye aktarıldığına bağlı olarak farklı davranışlara sahip birden fazla veri girişini destekler. Web uygulamanız, gelen etkinlikleri dinlerken aktarılan verileri gönderebilir ve alabilir.

Bu özellik, masaüstündeki web uygulamalarında paylaşım ve birlikte çalışabilirlik hakkında düşünme şeklimizi değiştirebilir. Uygulamalar arasında veri aktarımı için artık sıkıca bağlı entegrasyonlar gerekmiyor. Bunun yerine, kullanıcılara verileri istedikleri yere aktarma konusunda tam kontrol verebilirsiniz.

DataTransfer API ile mümkün olan etkileşimlere örnek. (Videoda ses yok.)

Veri aktarma

Başlamak için sürükle-bırak veya kopyala-yapıştır işlevini uygulamanız gerekir. Aşağıdaki örneklerde sürükle ve bırak etkileşimleri gösterilmektedir ancak kopyalama ve yapıştırma işlemi de benzerdir. Sürükle ve Bırak API'si hakkında bilginiz yoksa HTML5 sürükle ve bırak özelliğini açıklayan harika bir makale var. Bu makalede, özelliğin tüm ayrıntıları açıklanıyor.

MIME türü anahtarlı veriler sağlayarak harici uygulamalarla serbestçe etkileşim kurabilirsiniz. Çoğu WYSIWYG düzenleyici, metin düzenleyici ve tarayıcı, aşağıdaki örnekte kullanılan "primitive" MIME türlerine yanıt verir.

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 özelliğine dikkat edin. Bu, DataTransfer örneğini döndürür. Gördüğünüz gibi, bu nesne bazen başka adlara sahip özellikler tarafından döndürülür.

Veri aktarımını alma işlemi, verileri sağlama işlemiyle neredeyse aynıdır. Alınan etkinlikleri dinleyin (drop veya paste) ve anahtarları okuyun. Bir öğe sürüklenirken tarayıcı yalnızca verilerin type anahtarlarına erişebilir. Verilere yalnızca bırakma işleminden sonra erişilebilir.

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

Uygulamalarda yaygın olarak desteklenen üç MIME türü vardır:

  • text/html: HTML yükünü contentEditable öğelerinde ve Google Dokümanlar, Microsoft Word gibi zengin metin (WYSIWYG) düzenleyicilerde oluşturur.
  • text/plain: Giriş öğelerinin değerini, kod düzenleyicilerin içeriğini ve text/html'den gelen geri dönüşü ayarlar.
  • text/uri-list: URL çubuğuna veya tarayıcı sayfasına bırakıldığında URL'ye gider. Bir dizine veya masaüstüne bırakıldığında URL kısayolu oluşturulur.

text/html, WYSIWYG düzenleyiciler tarafından yaygın olarak kullanıldığından çok faydalıdır. HTML dokümanlarında olduğu gibi, veri URL'lerini veya herkese açık URL'leri kullanarak kaynakları yerleştirebilirsiniz. Bu, görselleri (örneğin, bir tuvalden) Google Dokümanlar gibi düzenleyicilere aktarırken iyi sonuç verir.

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

Kopyalama ve yapıştırma yoluyla aktarma

DataTransfer API'nin kopyalama-yapıştırma etkileşimleriyle kullanımı aşağıda gösterilmiştir. Pano etkinlikleri için DataTransfer nesnesinin clipboardData adlı bir özellik tarafından döndürüldüğünü unutmayın.

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

Özel veri biçimleri

Temel MIME türleriyle sınırlı değilsiniz. Aktarılan verileri tanımlamak için herhangi bir anahtarı kullanabilirsiniz. Bu, uygulamanızdaki tarayıcılar arası etkileşimler için yararlı olabilir. Aşağıda gösterildiği gibi, JSON.stringify() ve JSON.parse() işlevlerini kullanarak daha karmaşık verileri aktarabilirsiniz.

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

Web'i birbirine bağlama

Özel biçimler, kontrolünüzdeki uygulamalar arasındaki iletişim için harika olsa da verileri biçiminizi kullanmayan uygulamalara aktarırken kullanıcıyı sınırlar. Web'deki üçüncü taraf uygulamalarıyla bağlantı kurmak istiyorsanız evrensel bir veri biçimine ihtiyacınız vardır.

JSON-LD (Bağlantılı Veri) standardı bu amaç için idealdir. JavaScript'te hafiftir ve kolayca okunup yazılabilir. Schema.org, kullanılabilecek birçok önceden tanımlanmış tür içerir. Ayrıca özel şema tanımları da kullanılabilir.

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 türlerini kullanırken genel Thing türüyle başlayabilir veya kullanım alanınıza daha yakın bir tür (ör. Event, Person, MediaObject, Place) kullanabilirsiniz. Gerekirse MedicalEntity gibi çok spesifik türleri bile kullanabilirsiniz. TypeScript kullanırken schema-dts tür tanımlarındaki arayüz tanımlarını kullanabilirsiniz.

JSON-LD verilerini ileterek ve alarak daha bağlantılı ve açık bir web'i desteklemiş olursunuz. Aynı dili konuşan uygulamalarla, harici uygulamalarla derin entegrasyonlar oluşturabilirsiniz. Karmaşık API entegrasyonlarına gerek yoktur. Gerekli tüm bilgiler aktarılan verilerde yer alır.

Verileri herhangi bir (web) uygulama arasında kısıtlama olmadan aktarmak için tüm olasılıkları düşünün: takvimdeki etkinlikleri en sevdiğiniz yapılacaklar listesi uygulamasıyla paylaşma, sanal dosyaları e-postalara ekleme, kişileri paylaşma. Harika olurdu, değil mi? Bu iş sizinle başlar. 🙌

Endişeler

DataTransfer API şu anda kullanılabilir olsa da entegrasyon yapmadan önce dikkat etmeniz gereken bazı noktalar vardır.

Tarayıcı uyumluluğu

Masaüstü tarayıcılar, yukarıda açıklanan teknik için mükemmel destek sunarken mobil cihazlar bu tekniği desteklemez. Bu teknik, tüm büyük tarayıcılarda (Chrome, Edge, Firefox, Safari) ve işletim sistemlerinde (Android, ChromeOS, iOS, macOS, Ubuntu Linux ve Windows) test edilmiştir ancak maalesef Android ve iOS testi geçememiştir. Tarayıcılar gelişmeye devam ederken bu teknik şu anda yalnızca masaüstü tarayıcılarla sınırlıdır.

Keşfedilebilirlik

Sürükle-bırak ve kopyala-yapıştır, masaüstü bilgisayarda çalışırken kullanılan sistem düzeyinde etkileşimlerdir ve 40 yıldan uzun bir süre önce ilk GUI'lere dayanır. Dosyaları düzenlemek için bu etkileşimleri kaç kez kullandığınızı düşünün. Bu özellik web'de henüz çok yaygın değildir.

Kullanıcıları bu yeni etkileşim hakkında eğitmeniz ve özellikle bilgisayarlarla ilgili deneyimi şu ana kadar mobil cihazlarla sınırlı olan kişiler için bu etkileşimi tanınabilir hale getirecek kullanıcı deneyimi kalıpları oluşturmanız gerekir.

Erişilebilirlik

Sürükle ve bırak işlemi çok erişilebilir bir etkileşim olmasa da DataTransfer API, kopyala-yapıştır ile de çalışır. Kopyalama ve yapıştırma etkinliklerini dinlediğinizden emin olun. Bu işlem çok fazla ek çalışma gerektirmez ve kullanıcılarınız bu özelliği eklediğiniz için size minnettar kalır.

Güvenlik ve gizlilik

Bu tekniği kullanırken dikkat etmeniz gereken bazı güvenlik ve gizlilik hususları vardır.

  • Pano verileri, kullanıcının cihazındaki diğer uygulamalar tarafından kullanılabilir.
  • Üzerine sürüklediğiniz web uygulamaları, verilere değil, anahtar türlerine erişebilir. Veriler yalnızca bırakma veya yapıştırma işleminden sonra kullanılabilir.
  • Alınan veriler, diğer kullanıcı girişleri gibi ele alınmalı, kullanılmadan önce temizlenmeli ve doğrulanmalıdır.

Transmat yardımcı kitaplığını kullanmaya başlama

Uygulamanızda DataTransfer API'yi kullanmaya hazır mısınız? GitHub'daki Transmat kitaplığına göz atabilirsiniz. Bu açık kaynak kitaplık, tarayıcı farklılıklarını giderir, JSON-LD yardımcı programları sağlar, bırakma alanlarını vurgulamak için aktarım etkinliklerine yanıt veren bir gözlemci içerir ve mevcut sürükle ve bırak uygulamaları arasındaki veri aktarımı işlemlerini entegre etmenize olanak tanır.

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

Teşekkür

Luba Ertel tarafından Unsplash'te çekilen hero resmi.