Panodan resim yapıştırma işlevi Gmail ve Google Chrome 12+ içinde nasıl çalışır?


148

Google'dan , Chrome'un en son sürümünü kullanıyorsanız, resimleri doğrudan panodan bir Gmail iletisine yapıştırma yeteneğinden bahseden bir blog yazısı fark ettim . Bunu Chrome sürümümle (12.0.742.91 beta-m) denedim ve kontrol tuşlarını veya içerik menüsünü kullanarak harika çalışıyor.

Bu davranıştan yola çıkarak, Chrome'da kullanılan webkit'in en son sürümünün Javascript yapıştırma olayındaki resimlerle başa çıkabildiğini varsaymam gerekiyor, ancak böyle bir geliştirmeye yönelik herhangi bir referans bulamadım. İnanıyorum ZeroClipboard tuşa basma olaylara bağlar onun flaş işlevselliğini tetikleyebilir ve bu şekilde hiç olur bağlam menüsü aracılığıyla değil iş (ayrıca, ZeroClipboard çapraz tarayıcı ve sonrası bu Chrome ile çalışır diyor).

Öyleyse, bu nasıl çalışıyor ve işlevselliği etkinleştiren Webkit (veya Chrome) için geliştirme nerede yapıldı?


3
Görünüşe göre Firefox ile de rastgele çalışıyor. Bunun Firefox ile desteklenip desteklenmediğini bilen var mı?
Sébastien

Yanıtlar:


235

Bunu denemek için biraz zaman harcadım. Görünüşe göre yeni Clipboard API spesifikasyonunu takip ediyor . Bir "yapıştırma" olay işleyicisi tanımlayabilir, event.clipboardData.items'e bakabilir ve bir Blob almak için üzerlerinde getAsFile () çağırabilirsiniz. Bir Blobunuz olduğunda , içinde ne olduğunu görmek için üzerinde Dosya Okuyucuyu kullanabilirsiniz . Chrome'a ​​yeni yapıştırdığınız şeyler için bir veri URL'sini şu şekilde alabilirsiniz:

// window.addEventListener('paste', ... or
document.onpaste = function(event){
  var items = (event.clipboardData || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  for (index in items) {
    var item = items[index];
    if (item.kind === 'file') {
      var blob = item.getAsFile();
      var reader = new FileReader();
      reader.onload = function(event){
        console.log(event.target.result)}; // data url!
      reader.readAsDataURL(blob);
    }
  }
}

Bir veri url'sine sahip olduğunuzda, resmi sayfada görüntüleyebilirsiniz. Bunun yerine yüklemek istiyorsanız, readAsBinaryString'i kullanabilir veya FormData'yı kullanarak bir XHR'ye koyabilirsiniz .


6
Burada payetlere tutunmak, ancak event.clipboardData.items'in Safari 5.1'de neden 'tanımsız' göründüğüne dair bir fikriniz var mı? Veya Safari'de bir dosya / blob için pano içeriğini nasıl elde edersiniz? Chrome'da harika çalışıyor. Webkit'in webkit olacağını düşünürsünüz :(
Gavin Gilmour

7
@SenicaGonzalez, çünkü veriler yalnızca olay süresince var olur. Olaydan sonra kaybolur, yani nesneyi denetçide çevirip açmaya çalıştığınızda hiçbir şey görmezsiniz.
Nick Retallack

2
Bu görüntü verileriyle XMLHttpRequest'in nasıl gönderileceğine dair bir örnek verebilir misiniz? Bu gerçekten güzel olurdu: D
poitroae

1
XMLHttpRequest kullanarak bunu nasıl gönderebileceğiniz aşağıda açıklanmıştır, bunu uyguladıktan sonra bir bloga yazdım: blog.securevideo.com/2013/11/27/…
JT Taylor

1
Artık listedeki ilk öğe her zaman yapıştırdığınız dosya olmadığına göre, onu yapıştırılan dosyaları bulmak için öğeler arasında döngü oluşturacak şekilde güncelledim.
Nick Retallack

57

Nick'in cevabının hala işe yaraması için küçük değişikliklere ihtiyacı var gibi görünüyor :)

// window.addEventListener('paste', ... or
document.onpaste = function (event) {
  // use event.originalEvent.clipboard for newer chrome versions
  var items = (event.clipboardData  || event.originalEvent.clipboardData).items;
  console.log(JSON.stringify(items)); // will give you the mime types
  // find pasted image among pasted items
  var blob = null;
  for (var i = 0; i < items.length; i++) {
    if (items[i].type.indexOf("image") === 0) {
      blob = items[i].getAsFile();
    }
  }
  // load image if there is a pasted image
  if (blob !== null) {
    var reader = new FileReader();
    reader.onload = function(event) {
      console.log(event.target.result); // data url!
    };
    reader.readAsDataURL(blob);
  }
}

Örnek çalışan kod: http://jsfiddle.net/bt7BU/225/

Yani, nick cevapındaki değişiklikler şunlardı:

var items = event.clipboardData.items;

-e

var items = (event.clipboardData  || event.originalEvent.clipboardData).items;

Ayrıca yapıştırılan öğelerden ikinci öğeyi almam gerekiyordu (bir başka web sayfasından bir görüntüyü arabelleğe kopyalarsanız ilki text / html gibi görünüyor). Ben de değiştim

  var blob = items[0].getAsFile();

görüntüyü içeren öğeyi bulma döngüsüne (yukarıya bakın)

Nick'in cevabına doğrudan nasıl cevap vereceğimi bilmiyordum, umarım burada sorun yoktur: $ :)


1
Görüntü verilerini XMLHttpRequest olarak nasıl göndermeliyiz?
poitroae

Bunu okuyan diğerlerine, bu sorunun cevabı şimdi oraya dahil edilebilir: stackoverflow.com/questions/18055422/… :)
robintibor

4
Ben anlamıyorum Dosyaları tarayıcıya yapıştırdığımda clipboardData.items, google chrome'da her zaman boş kalıyor (Firefox çalışıyor). Chrome artık neredeyse IE'nin yaptığı kadar çok optimizasyona ihtiyaç duyuyor.
Tomáš Zato -

1
Küçük düzenleme: if (blob! = Null) {(veya başlatmada blob = null olarak ayarlayın)
Pancakeo

1
event.clipboardData.itemsen son Chrome'da benim için iyi çalıştı, ne zaman event.originalEvent...faydalı olduğundan emin değil misiniz?
Ruben Martinez Jr.


5

Web tarayıcıları ilerlemeye devam ediyor. Yakın zamanda şunu buldum:

Code Snippet - Javascript ile Pano Resimlerine Erişim

ve bu:

Paste Wasteland (veya onPaste olayının neden bir karmaşa olduğu)

İlk bağlantı, yalnızca Firefox ve Chrome'da JavaScript kullanarak pano resimleri almanın bir yolunu açıklar. İkinci bağlantı, aynı tekniğin IE'ye (bilinmeyen versiyon) uyarlandığından bahseden bir postscript içerir.


Firefox, Düzenle | Menü öğesini benim için yapıştırın, böylece Firefox'ta nasıl çalıştığını göremiyorum.
podperson

Yorum yapılırken bu bağlantılardan herhangi biri çalışmıyor.
Crazywako

2

Bildiğim kadarıyla -

HTML 5 özellikleriyle (Dosya API'si ve ilgili) - pano görüntü verilerine erişim artık düz javascript ile mümkün.

Ancak bu, IE üzerinde çalışmaz (IE 10'dan daha az herhangi bir şey). IE10 desteği hakkında da pek bir şey bilmiyorum.

IE için 'geri dönüş' seçenekleri olduğuna inandığım seçenekler ya Adobe'nin AIR api'sini kullanıyor ya da imzalı bir uygulama kullanıyor


1

Vay canına, bu harika. Henüz anlamak için gmail kaynağına dalmadım (sürükle / bırak işleviyle yaptım), ancak kromun zaten genişlettiği sürükle / bırak API'sinin bir uzantısı olduğunu tahmin ediyorum. Masaüstüne sürükleme özelliğinin nasıl çalıştığına dair iyi bir yazı var: http://www.thecssninja.com/javascript/gmail-dragout , en azından sizi doğru yöne yönlendirebilir.


0

Bu, projem için çalışan angular2 typcript'li bir örnekten. Umarım birine yardımcı olur. Mantık, diğer durumlarda da aynıdır.

https://gist.github.com/sandeepsuvit/a8ba77faebba260455985504be24aef7

İşte canlı bir uygulama:

https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.ts


1
Lütfen hangi süreci takip ettiğinizi açıklar mısınız? Bağlantıyı https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tskromda açabilir ve ardından herhangi bir web sitesinden bir görsele sağ tıklayabilirsiniz. Ardından sağlanan metin kutusuna yapıştırın. Bu şekilde çalışmalı.
Sandeep K Nair

web resim çalışmalarından kopyalanmıştır. Windows gezgininden görüntüleri denedim, bu yüzden o zamanlar çalışmıyordu. Windows gezgininden kopyalanan görüntüyü web sayfasına yapıştırmak için kullanmanın bir yolunu biliyor musunuz?
Battle Hawk

Bu seçeneği henüz denemedim. Umarım yerine bu kütüphanelerden bilgiler edinebilirsiniz https://github.com/layerssss/paste.js/, https://github.com/JoelBesada/pasteboard. Bu bağlantılarda deneyebileceğiniz demolar var.
Sandeep K Nair

event.clipboard Görüntüyü Windows işletim sistemi makinelerine yapıştırdığımda veriler boş. Bunun neden olduğunu kimse açıklayabilir mi?
Tunç Doğan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.