Перетаскивание HTML5 и загрузка нескольких файлов

#html #file #file-io #drag-and-drop

#HTML #файл #file-io #перетаскивание

Вопрос:

У меня есть HTML-форма, которая содержит поле ввода файла с возможностью выбора нескольких файлов, и у меня также есть функция перетаскивания, над которой я также работаю. Мой вопрос в том, как легко интегрировать обе эти функции, если это вообще возможно?

В идеале я хотел бы, чтобы пользователь выбирал свои файлы либо с помощью drag’n’drop, либо через диалоговое окно file. Как только пользователь закончит выбирать свои файлы, нажмите кнопку отправки формы для загрузки.

Я предполагаю, что основная неопределенность, которая у меня есть, заключается в том, как привязать файлы, которые были перетащены, к полю ввода файла для отправки формы.

Комментарии:

1. Где вы можете заставить это работать?

Ответ №1:

Я написал некоторый код jQuery, который делает именно это, скажите мне, работает ли это у вас.

 <!DOCTYPE html>
<html>
  <head>
    <title>Multiple DnD Uploader</title>
    <link rel="stylesheet" href="style.css" />
    <script type = "text/javascript" src = "../music/jquery.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
        $('#drop').change(function(event){
          files = event.target.files;
          $('#drop').css('display', 'none');
          for(var i = 0, len = files.length; i < len; i  ) {
            if((files[i].fileName "").substring((files[i].fileName "").length-4,(files[i].fileName "").length)=='.mp3'){
            $.ajax({
              type: "POST",
              url: "uploader.php?id=" i,
              contentType: "multipart/form-data",
              headers: {
                "X-File-Name" : files[i].fileName,
                "X-File-Size" : files[i].fileSize,
                "X-File-Type" : files[i].type
              },
              beforeSend:  function() {
                $('#info').append('<li class="indicator"><span class="label">File Name :</span> ' files[i].fileName ' | <span class="label">Size :</span> '   files[i].fileSize   ' | <img id="' i '" src="loading.gif" /></li>');
              },
              processData: false,
              data: files[i],
              success: function(data){
                $('#' data).attr('src', 'check.png');
              },error: function(data){
                $('#info').append('Error: '   data   '<br />');
              }
            });
            }else{
              $('#info').append('Error: Incorrect file type. Looking for .mp3');
            }
          }
        });
      });
    </script>
  </head>
  <body>
    <div id="drop">
      <h1>Drop files here</h1>
      <p>To add them as attachments</p>
      <input type="file" multiple="true" id="filesUpload" />
    </div>
    <div id="info">
    </div>
  </body>
</html>
  

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

 <?php
  $headers = array();
  foreach ($_SERVER as $k => $v){   
    if(substr($k, 0, 5) == "HTTP_"){
      $k = str_replace('_', ' ', substr($k, 5));
      $k = str_replace(' ', '-', ucwords(strtolower($k)));
      $headers[$k] = $v;
    }
  } 
  $file = new stdClass;
  $file->name = basename($headers['X-File-Name']);
  $file->size = $headers['X-File-Size'];
  $file->content = file_get_contents("php://input");
  if(file_put_contents('files/'.$file->name, $file->content))
    echo $_GET['id'];
?>
  

Комментарии:

1. Если я перетаскиваю файл в зону удаления, я хотел бы взять эти данные и добавить их в поле ввода файла, которое пользователь обычно нажимает, чтобы открыть диалоговое окно файла. Неясно, как это сделать или есть ли какие-либо проблемы с безопасностью. Кроме того, если я правильно понимаю, file input multiple действует как массив, так что при отправке формы будет отправлен массив данных, связанных с файлом.

2. Что ж, что вы можете сделать, это просто изменить успешный вызов jquery на что-то вроде этого: $('#files').append(files[data].fileName); Если я вас не неправильно понял.

Ответ №2:

Я не совсем уверен, как вы это делаете, поэтому я расскажу вам, как я это делаю, а затем попытаюсь ответить на ваш вопрос.

  1. Настройте прослушиватели событий для удаления и изменения события <input>.
    • для удаления: filesUpload.addEventListener("change", function () {traverseFiles(this.files);}, false);
    • для <ввода>: dropArea.addEventListener("drop", function (evt) {traverseFiles(evt.dataTransfer.files);}, false);
  2. traverseFiles то, что вы видите выше, — это функция, которая получает FileList (массив File файлов), которые являются частью File API. Затем эта функция вызывает функцию uploadFile для каждого File .
  3. uploadFile отправляет File асинхронно через ajax ( XMLHttpRequest.send(file) ).

Теперь, чтобы ответить на ваш вопрос, как привязать удаленные файлы к полю ввода: вы этого не делаете, вы просто делаете это другим способом. Вы создаете API или оболочку для загрузки файлов, а затем, если пользователь удаляет файлы, вы вызываете эту функцию-оболочку. Если пользователь нажимает на поле <ввод>, вы снова вызываете эту оболочку (как я сделал с traverseFiles).

Имеет смысл? Если этого не произойдет, скажите мне, какая часть, и я отредактирую этот ответ / расширю его.

Ответ №3:

 <input type=file multiple>
<div id='dropzone'>Drop Files Here</div>
  

события onchange и ondrop должны связать функцию с переменной, чтобы получить список файлов.

 var files=e.target.files||e.dataTransfer.files
  

читать это

Ответ №4:

Вы могли бы использовать «HTML5-File-Uploader», который предназначен для выполнения того, что вам нужно, а также для корректного изменения для старых браузеров:

https://github.com/gre/HTML5-File-Uploader/wiki

Я сам этого не пробовал.

В качестве альтернативы, вы могли бы взглянуть на эту страницу, которая предоставляет весь код, необходимый для выполнения этого самостоятельно:

http://robertnyman.com/2010/12/16/utilizing-the-html5-file-api-to-choose-upload-preview-and-see-progress-for-multiple-files/