DataTransfer API'yi kullanarak bariyerleri ortadan kaldırma

Kullanıcının tarayıcı penceresinin dışında veri paylaşmasına izin ver.

HTML5 Sürükle ve Bırak API'si ve Pano 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

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

Kaynak

Sürükleyip yapıştırma ve kopyalayıp yapıştırma etkileşimleri genellikle, basit metinleri A'dan B'ye aktarmak üzere bir sayfa içindeki etkileşimlerde kullanılır. Ancak çoğu zaman gözden kaçan şey, bu etkileşimlerin tarayıcı penceresinin ötesine geçmek için kullanılabilmesidir.

Hem tarayıcının yerleşik sürükle ve bırak özelliği hem de kopyalama ve yapıştırma işlemleri, web'de veya başka bir yerdeki 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ü web uygulamalarında paylaşım ve birlikte çalışabilirlik hakkındaki düşüncelerimizi değiştirebilir. Artık uygulamalar arasında veri aktarmak için sıkı bağlı entegrasyonlara gerek yok. Bunun yerine, kullanıcılara istedikleri yere veri aktarma konusunda tam kontrol sağlayabilirsiniz.

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

Veri aktarma

Başlamak için, sürükleyip bırakma veya kopyalayıp yapıştırma uygulamanız gerekir. Aşağıdaki örnekler sürükle ve bırak etkileşimlerini gösterir ancak kopyalayıp yapıştırma işlemleri benzerdir. Sürükle ve Bırak API'si hakkında bilginiz yoksa HTML5 sürükle ve bırak özelliğini açıklayan mükemmel bir makale var.

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 "ilkel" 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, bir DataTransfer örneği döndürür. Göreceğiniz gibi bu nesne bazen başka adlara sahip mülkler tarafından döndürülür.

Veri aktarımını alma ile hemen hemen aynı şekilde işlem yapılır. Alıcı etkinlikleri (drop veya paste) dinleyin ve anahtarları okuyun. Bir öğenin üzerine sürüklendiğinde tarayıcı yalnızca verilerin type anahtarlarına erişebilir. Verilere yalnızca bir düşüşten 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();
});

Uygulamalar arasında yaygın olarak desteklenen üç MIME türü vardır:

  • 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: text/html kodundaki giriş öğelerinin, kod düzenleyicilerin içeriğini ve yedeğin değerini ayarlar.
  • text/uri-list: URL çubuğunda veya tarayıcı sayfasında bırakma sırasında URL'ye gider. Bir dizin veya masaüstüne bırakıldığında bir URL kısayolu oluşturulur.

text/html ürününün WYSIWYG editörleri tarafından yaygın şekilde benimsenmesi bu uygulamayı son derece faydalı hale getiriyor. HTML dokümanlarında olduğu gibi, Veri URL'lerini veya herkese açık URL'leri kullanarak kaynakları yerleştirebilirsiniz. Bu yöntem, görsellerin (örneğin, bir tuvalden) Google Dokümanlar gibi düzenleyicilere dışa aktarılmasında iyi sonucu 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 ile aktarma

Kopyalama ve yapıştırma etkileşimleriyle DataTransfer API'nin kullanılması aşağıda gösterilmiştir. DataTransfer nesnesinin, pano etkinlikleri için clipboardData adlı bir mülk 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

Basit MIME türleriyle sınırlı değilsiniz. Aktarılan verileri tanımlamak için herhangi bir anahtar kullanabilirsiniz. Bu, uygulamanızda 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'e bağlanma

Özel biçimler, kontrolünüzdeki uygulamalar arasında iletişim için mükemmel olsa da biçiminizi kullanmayan uygulamalara veri aktarırken kullanıcıyı da sınırlandırır. 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ı bu konuda mükemmel bir seçimdir. Hafiftir ve JavaScript ile kolayca okunabilir ve üzerine yazılabilir. Schema.org, kullanılabilecek birçok önceden tanımlanmış 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 kullanım alanınıza daha yakın bir tür (ör. Event, Person, MediaObject, Place) kullanabilir, hatta gerekirse MedicalEntity gibi son derece spesifik türleri tercih edebilirsiniz. TypeScript kullandığınızda, schema-dts tür tanımlarındaki arayüz tanımlarını kullanabilirsiniz.

JSON-LD verilerini gönderip alarak daha bağlantılı ve açık bir web'i desteklemiş olursunuz. Aynı dili konuşan uygulamalar sayesinde harici uygulamalarla kapsamlı entegrasyonlar oluşturabilirsiniz. Karmaşık API entegrasyonlarına gerek yoktur. Gereken tüm bilgiler aktarılan verilere dahil edilir.

Herhangi bir (web) uygulaması arasında kısıtlama olmadan veri aktarma olanaklarının tümünü düşünün: Takvimdeki etkinlikleri favori yapılacaklar uygulamanızla paylaşma, e-postalara sanal dosya ekleme, kişileri paylaşma. Çok iyi olurdu, değil mi? Bu süreç sizinle başlıyor. 🙌

Endişeler

DataTransfer API şu anda kullanılabilir 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 destekler ancak mobil cihazlar desteklemez. Teknik, başlıca tüm tarayıcılarda (Chrome, Edge, Firefox, Safari) ve işletim sistemlerinde (Android, ChromeOS, iOS, macOS, Ubuntu Linux ve Windows) test edilmiş olsa da Android ve iOS testi geçemedi. Tarayıcılar gelişmeye devam etse de teknik şimdilik yalnızca masaüstü tarayıcılarla sınırlıdır.

Keşfedilebilirlik

Sürükleyip yapıştırma ve kopyalayıp yapıştırma işlemleri, masaüstü bilgisayarlarda çalışırken sistem düzeyindeki etkileşimlerdir. Bu etkileşimler köklerin 40 yıldan uzun bir süre önceki ilk GUI'lere kadar dayanır. Dosyaları düzenlemek için bu etkileşimleri kaç kez kullandığınızı düşünün. Bu özellik henüz web'de çok yaygın değil.

Kullanıcıları bu yeni etkileşim hakkında eğitmeniz ve özellikle şu ana kadar bilgisayar deneyimlerini yalnızca mobil cihazlarla sınırlandıran kullanıcılar için bunu anlaşılır kılmak amacıyla kullanıcı deneyimi kalıpları oluşturmanız gerekir.

Erişilebilirlik

Sürükleyip bırakma işlevi çok erişilebilir bir etkileşim değildir ancak DataTransfer API'yi kopyalayıp yapıştırma işleviyle de çalışır. Kopyala-yapıştır etkinliklerini dinlediğinizden emin olun. Bu işlem çok fazla çaba gerektirmez ve kullanıcılarınız bu özelliği eklediğiniz için size teşekkür eder.

Güvenlik ve gizlilik

Tekniği kullanırken dikkat etmeniz gereken bazı güvenlik ve gizlilik konuları vardır.

  • Kullanıcının cihazındaki diğer uygulamalar, panosundaki verilere erişebilir.
  • Üzerine sürüklediğiniz web uygulamaları, verilere değil, yazma tuşlarına erişebilir. Veriler yalnızca bırakma veya yapıştırma sırasında kullanılabilir hale gelir.
  • 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 kullanmaktan heyecan duyuyor musunuz? GitHub'daki Transmat kitaplığına göz atabilirsiniz. Bu açık kaynak kitaplık; tarayıcı farklılıklarını uyumlu hale getirir, 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 mevcut sürükleyip bırakma uygulamaları arasında veri aktarımı işlemlerini entegre etmenizi sağlar.

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'in Unsplash'teki hero resim.