Bagaimana cara tempel gambar dari fungsi clipboard bekerja di Gmail dan Google Chrome 12+?

148

Saya perhatikan sebuah posting blog dari Google yang menyebutkan kemampuan untuk menempelkan gambar langsung dari clipboard ke dalam pesan Gmail jika Anda menggunakan Chrome versi terbaru. Saya mencoba ini dengan versi Chrome saya (12.0.742.91 beta-m) dan bekerja sangat baik menggunakan tombol kontrol atau menu konteks.

Dari perilaku itu saya perlu berasumsi bahwa versi terbaru dari webkit yang digunakan di Chrome dapat menangani gambar dalam acara tempel Javascript, tetapi saya tidak dapat menemukan referensi apa pun untuk peningkatan semacam itu. Saya percaya ZeroClipboard mengikat acara penekanan tombol untuk memicu fungsionalitas flash-nya dan karena itu tidak akan berfungsi melalui menu konteks (juga, ZeroClipboard adalah cross-browser dan posting mengatakan ini hanya bekerja dengan Chrome).

Jadi, bagaimana cara kerjanya dan di mana perangkat tambahan dibuat untuk Webkit (atau Chrome) yang memungkinkan fungsionalitas?

Emil Lerch
sumber
3
Tampaknya itu berfungsi secara acak dengan Firefox juga. Adakah yang tahu kalau ini seharusnya didukung dengan Firefox?
Sébastien

Jawaban:

231

Saya menghabiskan beberapa waktu untuk bereksperimen dengan ini. Tampaknya semacam mengikuti spesifikasi API Clipboard baru . Anda dapat mendefinisikan event handler "tempel" dan lihat event.clipboardData.items, dan panggil getAsFile () pada mereka untuk mendapatkan Blob. Setelah Anda memiliki Blob, Anda dapat menggunakan FileReader di atasnya untuk melihat apa yang ada di dalamnya. Ini adalah cara Anda mendapatkan url data untuk hal-hal yang baru saja Anda tempel di Chrome:

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

Setelah Anda memiliki url data, Anda dapat menampilkan gambar di halaman. Jika Anda ingin mengunggahnya, Anda bisa menggunakan readAsBinaryString, atau Anda bisa memasukkannya ke XHR menggunakan FormData .

Nick Retallack
sumber
6
Berpegang teguh di sini, tetapi ada ide mengapa event.clipboardData.items tampaknya 'tidak terdefinisi' di Safari 5.1? Atau bahkan bagaimana cara mendapatkan konten clipboard untuk file / gumpalan di Safari? Bekerja sangat baik di Chrome. Anda akan berpikir webkit akan menjadi webkit :(
Gavin Gilmour
7
@SenicaGonzalez karena data hanya ada selama durasi acara. Setelah acara, itu hilang, jadi ketika Anda mencoba membalik objek di inspektur Anda tidak akan melihat apa-apa.
Nick Retallack
3
saya menjalankan ini di Firefox dan var blob = items [0] .getAsFile () throw TypeError: items tidak terdefinisi
chinna_82
2
Maukah Anda membuat contoh cara mengirimkan XMLHttpRequest dengan data gambar itu? Itu akan sangat menyenangkan: D
poitroae
1
Inilah cara Anda dapat mengirimkannya menggunakan XMLHttpRequest, saya menulisnya di blog setelah saya menerapkannya: blog.securevideo.com/2013/11/27/…
JT Taylor
56

Jawaban oleh Nick tampaknya perlu perubahan kecil untuk tetap bekerja :)

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

Contoh kode yang berjalan: http://jsfiddle.net/bt7BU/225/

Jadi, perubahan pada torehan jawaban adalah:

var items = event.clipboardData.items;

untuk

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

Juga saya harus mengambil elemen kedua dari item yang ditempelkan (yang pertama tampaknya menjadi teks / html jika Anda menyalin gambar dari halaman web lain ke buffer). Jadi saya berubah

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

ke loop menemukan item yang mengandung gambar (lihat di atas)

Saya tidak tahu bagaimana menjawab langsung jawaban Nick, semoga baik-baik saja di sini: $ :)

Robintibor
sumber
1
Bagaimana cara mengirim data gambar sebagai XMLHttpRequest?
poitroae
Untuk yang lain yang membaca ini, jawaban untuk pertanyaan ini dapat dimasukkan di sana sekarang: stackoverflow.com/questions/18055422/... :)
robintibor
4
Saya tidak mengerti. Ketika saya menempelkan file di browser, clipboardData.itemsselalu kosong di google chrome (Firefox berfungsi). Chrome sekarang membutuhkan optimasi yang hampir sama dengan IE dulu.
Tomáš Zato - Reinstate Monica
1
Suntingan kecil: if (gumpalan! = Null) {(atau atur gumpalan = null pada inisialisasi)
Pancakeo
1
event.clipboardData.itemsbekerja dengan baik untuk saya di Chrome terbaru, tidak yakin kapan event.originalEvent...ini berguna?
Ruben Martinez Jr.
5

Browser web terus bergerak maju. Saya baru-baru menemukan ini:

Cuplikan Kode - Mengakses Gambar Clipboard dengan Javascript

dan ini:

Paste Wasteland (atau, mengapa acara onPaste berantakan)

Tautan pertama menjelaskan cara mendapatkan gambar papan klip menggunakan JavaScript hanya di Firefox dan Chrome. Tautan kedua berisi postscript yang menyebutkan teknik yang sama diadaptasi ke IE (versi tidak diketahui).

Apodaca kaya
sumber
Firefox bahkan tidak mengaktifkan Edit | Tempelkan item menu untuk saya, jadi saya tidak melihat cara kerjanya di Firefox sama sekali.
podperson
Salah satu dari tautan tersebut tidak berfungsi pada saat berkomentar.
Crazywako
2

Sejauh yang aku tahu -

Dengan fitur HTML 5 (File Api dan yang terkait) - mengakses data gambar clipboard sekarang dimungkinkan dengan javascript biasa.

Namun ini gagal untuk bekerja pada IE (kurang dari IE 10). Tidak tahu banyak tentang dukungan IE10 juga.

Untuk IE, optiens yang saya percaya adalah opsi 'fallback' baik menggunakan api UDARA Adobe atau menggunakan applet yang ditandatangani

saurshaz
sumber
1

Wow, itu keren. Saya belum masuk ke sumber gmail untuk mengetahuinya (saya lakukan dengan fungsionalitas drag-out), tapi saya menduga itu adalah ekstensi dari API drag / drop yang telah diperluas chrome. Ada artikel yang layak tentang bagaimana fitur drag-to-desktop bekerja: http://www.thecssninja.com/javascript/gmail-dragout yang setidaknya mengarahkan Anda ke arah yang benar.

Mark Kahn
sumber
0

Ini dari contoh dengan naskah angular2 yang berfungsi untuk proyek saya. Semoga ini bisa membantu seseorang. Logika sama untuk kasus-kasus lain juga.

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

Berikut ini adalah implementasi langsung:

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

Sandeep K. Nair
sumber
1
Bisakah Anda jelaskan proses apa yang Anda ikuti? Anda dapat membuka tautan https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tsdalam chrome dan kemudian klik kanan pada gambar dari situs web mana pun. Kemudian tempel di kotak teks yang disediakan. Seharusnya bekerja seperti itu.
Sandeep K Nair
disalin dari karya gambar web. Saya mencoba gambar dari windows explorer, itu sebabnya itu tidak berfungsi saat itu. Apakah Anda tahu cara menangani gambar yang disalin dari windows explorer untuk menempelkannya di halaman web ?.
Battle Hawk
Saya belum mencoba opsi ini. Mudah-mudahan Anda bisa mendapatkan wawasan dari perpustakaan ini sebagai gantinya https://github.com/layerssss/paste.js/, https://github.com/JoelBesada/pasteboard. Ada demo yang tersedia di tautan ini yang dapat Anda coba.
Sandeep K Nair
event.clipboardData kosong ketika saya menempelkan gambar pada windows sistem operasi mesin. Adakah yang bisa menjelaskan mengapa ini terjadi?
Tunç Doğan