Як працює вставлення зображення з функцій буфера обміну в Gmail та Google Chrome 12+?


148

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

З цієї поведінки мені потрібно припустити, що остання версія веб-сайту, що використовується в Chrome, здатна обробляти зображення у події вставки Javascript, але я не зміг знайти жодних посилань на таке вдосконалення. Я вважаю, що ZeroClipboard прив'язується до подій натискання клавіш, щоб викликати її функціональність спалаху, і як таке не працюватиме в контекстному меню (також, ZeroClipboard є перехресним браузером, і повідомлення говорить, що це працює лише з Chrome).

Отже, як це працює і де було вдосконалено Webkit (або Chrome), який дозволяє функціонувати?


3
Здається, що він працює випадковим чином і з Firefox. Хтось знає, чи це має підтримуватися Firefox?
Себастьян

Відповіді:


231

Я провів деякий час, експериментуючи з цим. Здається, начебто слідкуйте за новою специфікацією API Clipboard 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
Тут чіпляються за соломку, але будь-які ідеї, чому, на думку Safari 5.1, event.clipboardData.items є "невизначеним"? Або навіть як отримати вміст буфера обміну для файлу / крапки в Safari? Чудово працює в Chrome. Ви б могли подумати, що webkit буде webkit :(
Gavin Gilmour,

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;

Також мені довелося взяти другий елемент із вставлених елементів (перший здається, що це текст / html, якщо ви копіюєте зображення з іншої веб-сторінки в буфер). Так я змінився

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

до циклу, що знаходить елемент, що містить зображення (див. вище)

Я не знав, як безпосередньо відповісти на відповідь Ніка, сподіваюся, що тут добре: $ :)


1
Як нам подати дані зображення як XMLHttpRequest?
poitroae

Для інших це читати, відповідь на це питання може бути там включений в даний час: stackoverflow.com/questions/18055422 / ... :)
robintibor

4
Я не розумію. Коли я вставляю файли в браузер, clipboardData.itemsу Google Chrome chrome завжди порожній (працює Firefox). Зараз для хромування потрібна майже така ж оптимізація, як раніше IE.
Томаш Зато - Відновити Моніку

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.
підперсон

Жодне з цих посилань не працює під час коментування.
Crazywako

2

Наскільки мені відомо -

Завдяки функціям HTML 5 (File Api та пов'язані з ними) - доступ до даних зображення буфера обміну тепер можливий за допомогою простого javascript.

Однак це не працює на IE (щонайменше, ніж IE 10). Не знаю багато про підтримку IE10 також.

Для IE оптимісти, які, на мою думку, є варіантами «резервного резервування», використовують або AIR-програму Adobe AIR Adobe, або використовують підписаний аплет


1

Нічого собі, це класно. Я ще не занурився в джерело gmail, щоб зрозуміти це (я це робив із функцією перетягування), але я здогадуюсь, що це розширення API перетягування / скидання, яке хром уже розширив. Існує гідний опис того, як працює функція перетягування на робочий стіл: 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в хромі, а потім натиснути правою кнопкою миші зображення на будь-якому веб-сайті. Потім вставте його в надане текстове поле. Це має працювати саме так.
Sandeep K Nair

скопійовано із творів веб-зображень. Я спробував зображення з Windows Explorer, тому це тоді не працювало. Чи знаєте ви яким-небудь способом обробити скопійоване зображення з Windows Explorer, щоб вставити його на веб-сторінку ?.
Battle Hawk

Я ще не пробував цей варіант. Сподіваюся , що ви можете отримати ідеї з цих бібліотек , а не https://github.com/layerssss/paste.js/, https://github.com/JoelBesada/pasteboard. На цих посиланнях є демонстрації, які можна спробувати.
Sandeep K Nair

event.clipboardДані порожні, коли я вставляв зображення на машини операційної системи Windows. Чи хтось може пояснити, чому це відбувається?
Tunç Doğan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.