DataTransfer API'yi kullanarak bariyerleri ortadan kaldırma

Kullanıcının tarayıcı penceresinin dışında veri paylaşabilmesini sağlayın.

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

Tarayıcı Desteği

  • 3
  • 12
  • 3,5
  • 4

Kaynak

Sürükle ve kopyala-yapıştır etkileşimleri genellikle bir sayfadaki basit metni A'dan B'ye aktarmak için kullanılan etkileşimlerde kullanılır. Ancak çoğu zaman göz ardı edilen şey, aynı etkileşimlerin tarayıcı penceresinin ötesine geçmek için kullanılabileceğidir.

Tarayıcının yerleşik sürükle ve bırak özellikleri ve kopyala-yapıştır etkileşimleri web'de olsun ya da olmasın diğer uygulamalarla iletişim kurabilir ve herhangi bir kaynağa bağlı değildir. API, verilerin aktarıldığı yere bağlı olarak farklı davranışlara sahip birden fazla veri girişini destekler. Web uygulamanız gelen etkinlikleri dinlerken aktarılan verileri gönderip alabilir.

Bu özellik, masaüstündeki web uygulamalarında paylaşım ve birlikte çalışabilirlik konusundaki düşüncelerimizi değiştirebilir. Uygulamalar arasında veri aktarımı için artık birbiriyle sıkı sıkıya bağlı entegrasyonlara gerek yoktur. Bunun yerine, kullanıcılara istedikleri yere verileri aktarmaları için tam kontrol verebilirsiniz.

DataTransfer API ile mümkün olan etkileşimlere örnek. (Video ses içermez.)

Veri aktarma

Başlamak için sürükleyip bırakma veya kopyalayıp yapıştırma işlemlerini uygulamanız gerekir. Aşağıdaki örneklerde sürükleme-bırakma etkileşimleri gösterilmektedir ancak kopyalama-yapıştırma işlemi benzerdir. Sürükle ve Bırak API'sine aşina değilseniz HTML5 Sürükle ve Bırak işlevini açıklayan harika bir makaleden ayrıntıları görebilirsiniz.

MIME türü anahtarlı veriler sağlayarak harici uygulamalarla serbestçe etkileşim kurabilirsiniz. Çoğu WYSIWYG düzenleyicisi, metin düzenleyici ve tarayıcı, aşağıdaki örnekte kullanılan "temel" 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 öğesinin bir ö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ı almak, aktarımı sağlamakla neredeyse aynıdır. Alma etkinlikleri (drop veya paste) dinleyin ve anahtarları okuyun. Bir öğenin üzerine sürüklerken, tarayıcı yalnızca verilerin type anahtarlarına erişebilir. Verilere yalnızca düşüş sonrasında 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 üç MIME türü yaygın olarak desteklenir:

  • text/html: HTML yükünü contentEditable öğelerinde ve Google Dokümanlar, Microsoft Word ve diğer zengin metin (WYSIWYG) düzenleyicilerinde oluşturur.
  • text/plain: Giriş öğelerinin, kod düzenleyicilerin içeriğinin ve text/html öğesindeki yedeğin değerini ayarlar.
  • text/uri-list: URL çubuğuna veya tarayıcı sayfasına bırakma sırasında URL'ye gider. Bir dizine veya masaüstüne bırakma işlemi sırasında bir URL kısayolu oluşturulur.

WYSIWYG düzenleyicileri tarafından yaygın olarak benimsenen text/html, bu yöntemi son derece kullanışlı hale getirir. HTML dokümanlarında olduğu gibi, kaynakları Veri URL'leri veya herkesin erişebileceği URL'leri kullanarak yerleştirebilirsiniz. Bu işlem, görselleri (örneğin bir tuvalden) Google Dokümanlar gibi düzenleyicilere dışa aktarırken faydalı olur.

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 aktar

DataTransfer API'nın kopyala-yapıştır etkileşimleriyle kullanımı aşağıda gösterilmektedir. DataTransfer nesnesinin, pano etkinlikleri için clipboardData adlı bir özellik tarafından döndürüldüğüne dikkat edin.

// 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 ancak 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, daha karmaşık verileri JSON.stringify() ve JSON.parse() işlevlerini kullanarak 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'e bağlanma

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

JSON-LD (Bağlı Veriler) standardı bunun için mükemmel bir adaydır. Hafiftir, JavaScript'ten okunması ve yazılması kolaydır. Schema.org, kullanılabilecek önceden tanımlanmış birçok tür içerir. Özel şema tanımları da bir seçenektir.

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 Event, Person, MediaObject, Place gibi kullanım alanınıza daha yakın bir türü ya da gerekirse MedicalEntity gibi çok spesifik türleri kullanabilirsiniz. TypeScript'i kullanırken schema-dts tür tanımlarındaki arayüz tanımlarını kullanabilirsiniz.

JSON-LD verilerini iletip alarak daha bağlantılı ve açık bir web'i desteklersiniz. Aynı dili konuşan uygulamalarla harici uygulamalarla derin entegrasyonlar oluşturabilirsiniz. Karmaşık API entegrasyonlarına gerek yoktur. Gerekli tüm bilgiler, aktarılan verilere dahil edilir.

Herhangi bir (web) uygulama arasında kısıtlama olmaksızın veri aktarımına ilişkin tüm olanakları düşünün: Bir takvimden favori ToDo uygulamanıza etkinlik paylaşımı, e-postalara sanal dosyalar ekleme, kişileri paylaşma. Çok iyi olur, değil mi? Bu sizinle başlıyor! 🙌

Endişeler

DataTransfer API şu anda kullanılabilir durumda olsa da entegrasyondan önce bilinmesi gereken bazı noktalar vardır.

Tarayıcı uyumluluğu

Masaüstü tarayıcıların tümü yukarıda açıklanan tekniği mükemmel bir şekilde desteklerken mobil cihazlar destek etmez. Teknik, tüm önemli tarayıcılarda (Chrome, Edge, Firefox, Safari) ve işletim sistemlerinde (Android, ChromeOS, iOS, macOS, Ubuntu Linux ve Windows) test edilmiştir ancak ne yazık ki Android ve iOS testi geçemedi. Tarayıcılar geliştirilmeye devam etse de, teknik şimdilik yalnızca masaüstü tarayıcılarla sınırlıdır.

Keşfedilebilirlik

Sürükle ve kopyala-yapıştır, bir masaüstü bilgisayarda çalışırken kökleri 40 yıldan daha uzun bir süre önceki ilk GUI'lere kadar geri alan sistem düzeyindeki etkileşimlerdir. Dosyaları düzenlemek için bu etkileşimleri kaç kez kullandığınızı düşünün. Bu henüz web'de çok yaygın bir uygulama değildir.

Kullanıcıları bu yeni etkileşim hakkında eğitmeniz ve özellikle de şu ana kadar bilgisayar deneyimi mobil cihazlarla sınırlı olan kişiler için bunun anlaşılmasını sağlayacak kullanıcı deneyimi kalıpları oluşturmanız gerekir.

Erişilebilirlik

Sürükleme işlevi erişilebilir bir etkileşim değildir, ancak DataTransfer API'sı kopyala-yapıştır özelliğiyle de çalışır. Kopyalama ve yapıştırma etkinliklerini dinlediğinizden emin olun. Fazladan işlem yapmanız gerekmez ve kullanıcılarınız, uygulamanızı eklediğiniz için size minnettar olur.

Güvenlik ve gizlilik

Bu tekniği kullanırken güvenlik ve gizlilikle ilgili dikkat etmeniz gereken bazı noktalar vardır.

  • Pano verileri, kullanıcının cihazındaki diğer uygulamalar tarafından kullanılabilir.
  • Sürüklediğiniz web uygulamalarının verilere değil yazma tuşlarına erişimi vardır. Veriler yalnızca bırakıldığında veya yapıştırıldığında kullanılabilir hale gelir.
  • Alınan veriler, diğer kullanıcı girişleri gibi ele alınmalıdır. Bu nedenle, kullanılmadan önce temizlenip doğrulanmalıdır.

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

Uygulamanızda DataTransfer API'sını kullanmayı düşünüyor musunuz? GitHub'daki Transmat kitaplığına göz atabilirsiniz. Bu açık kaynak kitaplık tarayıcı farklılıklarını hizalar, JSON-LD yardımcı programları sağlar, bırakma alanlarını vurgulamak için aktarım etkinliklerine yanıt verecek bir gözlemci içerir ve veri aktarımı işlemlerini mevcut sürükle ve bırak uygulamaları arasında 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'teki lokomotif resim.