Перетащите файл в Google Chrome / Chromium и Safari?

65

Загрузка файлов с перетаскиванием может быть выполнена в Firefox 3.6.

Поиск Google для загрузки и выгрузки файла html5 с перетаскиванием -gmail дает такие вещи, как:

Во всех этих руководствах используется FileReader (или Firefox 3.6, устаревший getAsBinary, который ни один другой браузер не поддерживает).

Однако недавно Google опубликовал обновление для Gmail, которое позволило загружать файлы с перетаскиванием в Chromium, а также Firefox, и У Chromium нет FileReader. Я использую последний Chromium в ночное время, и он может перетаскивать файлы загрузки, не поддерживая FileReader.

Я видел, как кто-то упоминал, что перетаскивание перетаскивания может быть возможно, перетаскивая его на <input type="file" />, но это может поддерживать только один файл за раз, в то время как загрузчик Gmail может обрабатывать несколько файлов, перетаскиваемых на него, явно не то, что они делают.

Итак, вопрос в том, как они это делают? Как вы поддерживаете Xromium для загрузки файлов HTML5? Кроме того, можете ли вы поддерживать Safari?

  • 2
    PS Чтение исходного кода довольно сложно, так как исходный код Gmail довольно хорошо запутан в результате всей оптимизации, которую они проводят над ним.
  • 1
    PPS FileList HTML- <input type="file" /> доступен только для чтения, поэтому вы не можете просто перенести файл перетаскивания в один из них.
Показать ещё 2 комментария
Теги:

9 ответов

33
Лучший ответ

ПРЕДУПРЕЖДЕНИЕ: Это код совместимости для очень старых версий Safari и Chrome. Современные браузеры поддерживают API FileReader; здесь один учебник: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Этот код теперь полезен только тогда, когда по какой-то причине вам необходимо поддерживать Safari 5 и старше, или Chrome 6 и старше.


Одна из возможностей заключается в использовании метода, используемого в SwellJS:

Используйте <input type="file" multiple="multiple" /> следующим образом:

<form method="post" enctype="multipart/form-data" id="uploadform">
  <input type="file" name="dragupload[]" multiple="multiple"
  onchange="if (this.value) document.getElementById('uploadform').submit();" />
</form>

Элемент ввода может быть стилизован, чтобы иметь opacity: 0 и позиционировать (абсолютно) над элементом, который принимает закачки. Вся форма может быть помещена внутри iframe для поведения псевдо-Ajax. И элемент upload может быть скрытым слоем, пока что-то не перетаскивается через него.

Такой iframe будет выглядеть так:

<script>
<!--
  var entered = 0;
-->
</script>
<body ondragenter="entered++;document.getElementById('uploadelement').style.display='block'" ondragleave="entered--;if (!entered) document.getElementById('uploadelement').style.display='none'">
  <form method="post" enctype="multipart/form-data" id="uploadform">
    Things can be dragged and dropped here!
    <input type="file" id="uploadelement" name="dragupload[]" multiple="multiple" onchange="if (this.value) { document.getElementById('uploadform').submit(); }" style="display:none;position:absolute;top:0;left:0;right:0;bottom:0;opacity:0;" />
  </form>
</body>

Это нужно делать только при обнаружении Safari или Chrome (поскольку другие браузеры не поддерживают перетаскивание на элементы <input type="file" />) и могут использоваться в сочетании с событием HTML5 drop для Firefox 3.6 +.

Я не могу сказать, используется ли этот метод Gmail, но он, безусловно, тоже работает.

  • 0
    Трюк увеличения / уменьшения количества записей в вашем коде шоу / скрытия действительно удобен.
  • 0
    Спасибо тебе за этот пост. Можно ли здесь сделать ссылку на полный пример? тот, который может включать в себя код на стороне сервера? или просто объясните (на asp.net), как я могу получить доступ к файлам, которые были отправлены из этой формы ("uploadForm")
13

Вы можете быть заинтересованы в чем-то более совместимом с технологиями и браузерами.

Мне кажется, что Plupload делает это хорошо, поддерживая следующие функции:

  • Чанкинг
  • Drag/Drop
  • Изменение размера PNG
  • Изменение размера JPEG
  • Фильтрация типов
  • Загрузка потока
  • Многостраничная загрузка
  • Ограничение размера файла
  • Прогресс загрузки

для большинства следующих технологий:

  • Вспышка
  • Gears
  • HTML 5
  • Silverlight
  • BrowserPlus

И да, с 2010.05.27, он поддерживает drag/drop для HTML5, запущенного в бета-версии Chrome.

  • 0
    Я только что проверил его на Chrome 6 для Mac: он не работает.
  • 0
    Ой? Вы пробовали "HTML 5 runtime" этой страницы? plupload.com/example_all_runtimes.php
Показать ещё 4 комментария
10

У меня есть кое-что работающее в Chrome после много, много, много детективной работы. Это работает только в Chrome. В Safari он замерзает. В Firefox это не позволит мне удалить файл. IE вместо этого отбрасывает файл. Даже в Chrome перетаскивание работает только один раз, по какой-то причине, после чего вам нужно обновить страницу. (Возможная причина этого в том, что с обработчиками событий что-то не так.)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <script type="text/javascript">
            window.onload = function () {
                var div = document.getElementById('div');
                div.ondragenter = div.ondragover = function (e) {
                    e.preventDefault();
                    e.dataTransfer.dropEffect = 'copy';
                    return false;
                }
                div.ondrop = function (e) {
                    for (var i = 0; i < e.dataTransfer.files.length; i++) { // e.dataTransfer is a DataTransfer object (https://developer.mozilla.org/En/DragDrop/DataTransfer), e.dataTransfer.files is a FileList object (https://developer.mozilla.org/en/DOM/FileList)
                        var file = e.dataTransfer.files[i]; // file is a File object (https://developer.mozilla.org/en/DOM/File)

                        var xhr = new XMLHttpRequest;
                        xhr.open('post', 'handler.php', true);
                        xhr.onreadystatechange = function () {
                            if (this.readyState != 4)
                                return;
                            document.body.innerHTML += '<pre>' + this.responseText + '</pre>';
                        }
                        xhr.setRequestHeader('Content-Type', 'multipart/form-data');
                        xhr.setRequestHeader('X-File-Name', file.fileName);
                        xhr.setRequestHeader('X-File-Size', file.fileSize);
                        xhr.send(file); // For some reason sending the actual File object in Chrome works?
                    }

                    e.preventDefault();
                    return false;
                }
            }
        </script>
    </head>
    <body>
        <div id="div" style="width: 100%; height: 200px; border: 1px solid blue">Drop here</div>
    </body>
</html>

handler.php:

    // This is not a true file upload. Instead, it sends the raw data directly.
    echo htmlentities(file_get_contents('php://input'));
  • 3
    Использование document.body.innerHTML + = уничтожает события dom. Избегание этого решит вашу проблему.
  • 0
    отлично работает, мне сказал разработчик gmail, что вы должны использовать dropEffect = 'move' для FF3.6 +, еще не тестировали в FF, поэтому не уверены, требуется ли это по-прежнему
2

Вы можете использовать библиотеку html5uploader: http://code.google.com/p/html5uploader/

Он работает с Firefox, Safari и Chrome.

2

Для нашего собственного приложения мы перетаскиваем только для FireFox. Мы возвращаемся к традиционной загрузке iframe для других. Чтобы обнаружить, что перетаскивание поддерживается, мы запускаем этот код:

if (typeof(window.File) == 'object' && typeof(window.FileReader) == 'function' && typeof(window.FileList) == 'object') {
   // DnD is supported!
}

Надеюсь, что это полезно для некоторых.

  • 0
    Спасибо - это полезно :)
  • 0
    Вы упоминаете, что перетаскиваете только для FireFox, но для тех, кто может использовать этот код, Safari 5 (Windows) вернет false для window.FileReader Проверка window.FileReader , даже если он отлично обрабатывает window.FileReader файлов. Все еще ищите надежное средство обнаружения возможностей браузера для перетаскивания файлов ...
2

Вам не нужно использовать iframe для загрузки псевдо-ajax. Chrome и Safari поддерживают XHR2 загружает с событиями прогресса, чтобы вы могли делать индикаторы выполнения и т.д.

  • 0
    ... да, это очевидно. Проблема здесь в том, что все учебники, которые я видел, используют FileReader или getAsBinary() (то есть функции, которые не поддерживает Chrome) для загрузки файла в XHR2. Я сомневаюсь, что это необходимо , так что я в основном делаю здесь, спрашиваю, как можно поступить, если бы кто-то хотел поддержку Chrome.
1

Последний загружаемый файл поддержки браузера. Вы можете использовать:

xhr = new XMLHttpRequest();     
xhr.open('POST', targetPHP, true);
var formData = new FormData();
formData.append('upload',file);
xhr.send(formData);

Вам не нужно устанавливать границу или любую голову, так же, как это хорошо работает. Я проверил этот код в client: firefox 6.02 и в хроме 13. server: tomcat с "spring mvc"

0

Задайте несколько атрибутов:

input type="file" name= "file1" multiple = "multiple" class= "DropHere"

и используйте этот класс CSS DropHere:

.DropHere
{
    height: 100px;
    padding: 3px;
    border: 2px dashed #555;
    border-radius: 5px;
    cursor: default;
    background-image:url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='100px' width='220px'><text x='55' y='75' font-size='20'>or drop files here</text></svg>");
    background-repeat: no-repeat;
}

Поле файла будет выглядеть следующим образом:

Изображение 3622

Если вы используете asp.net, вам также может понравиться эта статья, я написал "Несколько загрузок файлов с индикатором выполнения и перетаскиванием": http://www.codeproject.com/Articles/818561/Multiple-file-upload-with-progress-bar-and-drag-an

0

вы можете использовать FormData для хранения файла, а затем загрузить его. например,

function setUp(){
  var dropContainer = document.getElementById("container");
  dropContainer.addEventListener("drop",dropHandler,false);
  dropContainer.addEventListener("dragenter", function(event){event.stopPropagation();event.preventDefault();}, false);
  dropContainer.addEventListener("dragover", function(event){event.stopPropagation();event.preventDefault();}, false);
  dropContainer.addEventListener("drop", dropHandler, false);
  getResult()
}
function dropHandler(event){
  var files = event.dataTransfer.files;
  var count = files.length;
  form = new FormData();
  for(var i= 0;i<count;i++){
    form.append("file"+i, files[i]);
  }
  sendData();
}
function sendData(){
  var xhr = new XMLHttpRequest();  
  xhr.upload.addEventListener("progress", uploadProgress, false);  
  xhr.addEventListener("load", uploadComplete, false);
  xhr.addEventListener("error", uploadFailed, false);  
  xhr.open("POST", "/upload");
  xhr.send(form);
  var progressBar = document.getElementById('progressBar');
  progressBar.style.display = 'block';
  progressBar.style.width = '0px';
}

демо здесь (http://flexinnerp.appspot.com/) просто наслаждайтесь:)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню