Как я могу получить доступ к вставленному файлу в браузерах webkit? (как Google Chrome)

Было бы очень удобно, если бы можно было вставлять изображения сюда, на Stack Exchange, вместо того, чтобы вмешиваться в диалог файла. Подобная функция была (есть?) реализована здесь, но только для браузеров Webkit.

Я разрабатывал пользовательский скрипт, который делает это. Забавно, что мне так и не удалось получить файл (который отличается из необработанных данных изображения) из буфера обмена в браузерах Webkit, а в Firefox это работает.

Решение для фаерфокса:

  div.addEventListener('paste', function(event){
    //I'm actually not sure what should event.originalEvent be. I copypasted this
    var items = (event.clipboardData || event.originalEvent.clipboardData);
    console.log("paste", items);
    //Try to get a file and handle it as Blob/File
    var files = items.items || items.files;
    if(files.length>0) {  
      //Being lazy I just pick first file
      var file = files[0];
      //handle the File object
      _this.processFile(file);

      event.preventDefault();
      event.cancelBubble = true;
      return false;
    }
  });

Прежде чем у Chrome не было такой хорошей документации, как у Firefox (я имею в виду MDN), я попытался проверить, что происходит. Я скопировал файл и вставил его в Google Chrome (v39). Вот что я получаю в объекте DataTransfer в консоли:

вставить событие Google Chrome

Для справки, вот то же событие в Firefox:

вставить файлы событий firefox

Два других массива, items и types, отсутствуют в реализации Firefox. Когда я копирую текст или необработанные данные изображения, Chrome представляет их как DataTransferItem. Я понял, что лучше игнорировать те:

  //Being lazy I just pick first file
  var file = files[0];
  //GOOGLE CHROME
  if(file.getAsFile) {
    console.log("DataTransferItem:", file);
    //HTML or text will be handled by contenteditable div
    if(file.type!="text/plain" && file.type!="text/html") {
      //handle the File object
      _this.processFile(file.getAsFile());
    }
  }
  else 
    ...

До сих пор мне никогда не приходило в голову получить что-то еще, кроме text/plain или text/html. Для них .getAsFile возвращает null.

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


person Tomáš Zato - Reinstate Monica    schedule 03.12.2014    source источник
comment
Следуйте этой ошибке для проблемы с Chrome: crbug.com/316472 . И вас также может заинтересовать это для связанной с Firefox проблемы: bugzil.la/891247 . Обе команды, кажется, пытаются добиться того, чтобы их реализации более точно соответствовали спецификации/друг другу.   -  person Noyo    schedule 03.12.2014


Ответы (1)


Наш волшебный соус просто:

$('body').bind('paste', handlepaste);

Где handlepaste очень похоже на ваше, так что для Chrome все должно работать.

К сожалению, приведенное выше полностью не работает для FF, и мы не хотим добавлять contenteditable где-либо (в частности, учитывая, что он должен быть в фокусе, чтобы это работало, и мы не хотим красть фокус) .

person Oded    schedule 20.01.2015
comment
Я думал, что .bind равно .addEventListener. Если нет, то какая разница? Я не хочу включать jQuery в пользовательский скрипт только из-за этого... Также вставка file в contenteditable не вставляет его как изображение. Это работает только для изображений data. - person Tomáš Zato - Reinstate Monica; 20.01.2015
comment
@TomášZato - в наши дни это почти так. Я также говорю о вставке изображений, а не файлов. - person Oded; 20.01.2015