HTML5拖放和多文件上传

5
我有一个包含文件输入字段的HTML表单,可以多选文件,并且我还在开发拖放功能。我的问题是如何将这两个功能无缝集成,如果可能的话?
理想情况下,我希望用户通过拖放或文件对话框选择文件。一旦用户完成文件选择,点击表单提交按钮即可上传。
我想最主要的不确定因素是如何将拖放的文件绑定到文件输入字段以进行表单提交。

你能让这个工作起来吗? - Helen Araya
4个回答

1

我不是完全确定你是怎么做的,所以我会告诉你我的方法,然后再试着回答你的问题。

  1. 为放置和的更改事件设置事件侦听器。
    • 对于放置:filesUpload.addEventListener("change", function () {traverseFiles(this.files);}, false);
    • 对于<input>:dropArea.addEventListener("drop", function (evt) {traverseFiles(evt.dataTransfer.files);}, false);
  2. 您在上面看到的 traverseFiles 是一个函数,它获取 FileList ( File 的数组),它们是File API 的一部分。然后,该函数为每个 File 调用 uploadFile 函数。
  3. uploadFile 通过ajax异步发送 File XMLHttpRequest.send(file))。
现在来回答你的问题“如何将拖放的文件绑定到输入字段”:你不需要这样做,你可以采用另一种方式。你可以创建一个API或者上传文件的包装器,然后如果用户拖放文件,你就调用这个包装器函数。如果用户点击字段,你也可以再次调用这个包装器(就像我使用traverseFiles一样)。
有道理吗?如果不行,请告诉我哪一部分,我会编辑这个答案/扩展它。

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'];
?>

如果我将文件拖到放置区,我想将该数据附加到用户通常单击以获取文件对话框的文件输入字段中。目前不清楚如何处理此操作或是否存在任何安全问题。另外,如果我理解正确,文件输入多个作为数组,因此表单提交将发送一组与文件相关的数据。 - mac2017
嗯,你可以做的就是将jquery的成功调用更改为这样:
$('#files').append(files[data].fileName);
除非我误解了你的意思。
- Vap0r

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

onchange和ondrop事件应该绑定一个带有变量的函数来获取文件列表。

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

阅读此文


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接