Как работает вставка изображения из буфера обмена в Gmail и Google Chrome 12+?

148

Я заметил сообщение в блоге от Google, в котором упоминается возможность вставлять изображения непосредственно из буфера обмена в сообщение Gmail, если вы используете последнюю версию Chrome. Я попробовал это с моей версией Chrome (12.0.742.91 beta-m), и она прекрасно работает, используя клавиши управления или контекстное меню.

Исходя из этого, я должен предположить, что последняя версия webkit, используемая в Chrome, может работать с изображениями в событии вставки Javascript, но мне не удалось найти какие-либо ссылки на такое улучшение. Я полагаю, что ZeroClipboard связывается с событиями нажатия клавиш, чтобы вызвать его функциональность во флэш-памяти, и поэтому не будет работать через контекстное меню (также ZeroClipboard является кросс-браузерным, и в сообщении говорится, что это работает только с Chrome).

Итак, как это работает и где было сделано усовершенствование Webkit (или Chrome), которое обеспечивает функциональность?

Эмиль Лерх
источник
3
Похоже, что это работает случайным образом с Firefox. Кто-нибудь знает, должно ли это поддерживаться Firefox?
Себастьян

Ответы:

231

Я провел некоторое время, экспериментируя с этим. Кажется, что-то вроде новой спецификации API буфера обмена . Вы можете определить обработчик события «вставить» и посмотреть на event.clipboardData.items и вызвать getAsFile () для них, чтобы получить Blob. Когда у вас есть BLOB-объект, вы можете использовать FileReader, чтобы увидеть, что в нем есть. Вот как вы можете получить URL-адрес для данных, которые вы только что вставили в 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);
    }
  }
}

Когда у вас есть URL-адрес данных, вы можете отобразить изображение на странице. Если вы хотите загрузить его вместо этого, вы можете использовать readAsBinaryString, или вы можете поместить его в XHR, используя FormData .

Ник Реталлак
источник
6
Здесь хватается за соломинку, но есть ли идеи, почему event.clipboardData.items кажется «неопределенным» в Safari 5.1? Или даже как получить содержимое буфера обмена для файла / блоба в Safari? Прекрасно работает в Chrome. Вы могли бы подумать, что webkit будет webkit :(
Гэвин Гилмор
7
@SenicaGonzalez, потому что данные существуют только на время события. После события оно исчезло, поэтому при попытке открыть объект в инспекторе вы ничего не увидите.
Ник Реталлак
3
я запускаю это на Firefox и var blob = items [0] .getAsFile () выбрасываю TypeError: items не определено
chinna_82
2
Не могли бы вы привести пример, как отправить запрос XMLHttpRequest с данными этого изображения? Это было бы очень приятно: D
poitroae
1
Вот как вы можете сообщить, что с помощью XMLHttpRequest я написал это в блоге после того, как реализовал его: blog.securevideo.com/2013/11/27/…
JT Taylor
56

Кажется, что ответ Ника требует небольших изменений, чтобы все еще работать :)

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

Пример работающего кода: http://jsfiddle.net/bt7BU/225/

Таким образом, изменения в ответе ников были:

var items = event.clipboardData.items;

в

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

Также мне пришлось взять второй элемент из вставленных элементов (первый кажется text / html, если вы копируете изображение из другой веб-страницы в буфер). Итак, я изменился

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

в цикле поиска элемента, содержащего изображение (см. выше)

Я не знал, как ответить прямо на ответ Ника, надеюсь, здесь все в порядке: $ :)

robintibor
источник
1
Как мы должны представить данные изображения в виде XMLHttpRequest?
poitroae
Для тех, кто читает это, ответ на этот вопрос может быть включен там сейчас: stackoverflow.com/questions/18055422/… :)
robintibor
4
Я не понимаю Когда я вставляю файлы в браузер, clipboardData.itemsв google chrome всегда пусто (работает Firefox). Chrome теперь нуждается почти в такой же оптимизации, как раньше.
Томаш Зато - Восстановить Монику
1
Небольшое редактирование: if (blob! = Null) {(или установить blob = null при инициализации)
Pancakeo
1
event.clipboardData.itemsу меня нормально работал на последнем Chrome, не уверен, когда event.originalEvent...пригодится?
Рубен Мартинес-младший
5

Веб-браузеры продолжают идти вперед. Я недавно нашел это:

Фрагмент кода - Доступ к изображениям буфера обмена с помощью Javascript

и это:

Paste Wasteland (или, почему событие onPaste - беспорядок)

Первая ссылка описывает способ получения изображений из буфера обмена с использованием JavaScript только в Firefox и Chrome. Вторая ссылка содержит постскриптум, в котором упоминается тот же метод, который был адаптирован для IE (неизвестная версия).

Богатая Аподака
источник
Firefox даже не активирует Редактировать | Вставьте для меня пункт меню, чтобы я вообще не видел, как он работает в Firefox.
podperson
Ни одна из этих ссылок не работает во время комментирования.
Crazywako
2

Насколько я знаю -

С функциями HTML 5 (File Api и связанными с ними) - доступ к данным изображения буфера обмена теперь возможен с простым javascript.

Это, однако, не работает на IE (что-либо меньше, чем IE 10). Не знаю много о поддержке IE10 также.

Для IE варианты, которые, как я считаю, являются «запасными», либо используют API-интерфейс Adobe AIR, либо используют подписанный апплет.

saurshaz
источник
1

Ух ты, круто. Я еще не углубился в исходный код gmail, чтобы выяснить это (я сделал это с помощью функции перетаскивания), но я предполагаю, что это расширение API перетаскивания, которое Chrome уже расширило. Есть хорошая статья о том, как работает функция перетаскивания на рабочий стол: http://www.thecssninja.com/javascript/gmail-dragout, которая, по крайней мере, может указать вам правильное направление.

Марк Кан
источник
0

Это из примера с машинописью angular2, которая работает для моего проекта. Надеюсь, это кому-нибудь поможет. Логика такая же, как и в других случаях.

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

Вот живая реализация:

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

Сандип К Наир
источник
1
Не могли бы вы объяснить, каким процессом вы следовали? Вы можете открыть ссылку https://stackblitz.com/edit/angular-f7kcny?file=app/app.component.tsв Chrome, а затем щелкнуть правой кнопкой мыши изображение с любого веб-сайта. Затем вставьте его в предоставленное текстовое поле. Это должно работать таким образом.
Сандип К Наир
скопированы из веб-изображения работ. Я попробовал изображения из проводника Windows, поэтому он не работал тогда. Вы случайно не знаете, как обработать скопированное изображение из проводника Windows, чтобы вставить его на веб-страницу?
Боевой Ястреб
Я еще не пробовал эту опцию. Надеюсь , что вы можете получить идеи из этих библиотек , а не https://github.com/layerssss/paste.js/, https://github.com/JoelBesada/pasteboard. По этим ссылкам доступны демоверсии, которые вы можете попробовать.
Сандип К Наир
event.clipboardData пуст, когда я вставил изображение на машины с операционной системой Windows. Кто-нибудь может объяснить, почему это происходит?
Tunç Doğan