【问题标题】:File drag and drop in IE11 and FirefoxIE11和Firefox中的文件拖放
【发布时间】:2016-11-11 21:42:31
【问题描述】:

我正在尝试创建一个可以拖动图像文件进行上传的下拉框。这在 Chrome 和 Edge 中运行良好。但是,我在 Firefox 和 IE 11 中遇到了问题。例如,在 IE 11 中,当我单击浏览按钮时,会弹出一个窗口,标题为“选择要上传的文件”。如果我单击图像并单击“打开”它可以正常工作,但我无法将任何文件拖出窗口。但是,如果我打开文件资源管理器,我可以从文件资源管理器窗口拖放图像。类似的事情发生在 Firefox 中。我可以很好地从文件资源管理器中拖动图像,但是当我尝试从标题为“文件上传”的弹出窗口中拖动时,我得到一个带有圆圈和红色斜线的幽灵图像。这里的一些线程建议使用 dragstart 函数,但这似乎不起作用,可能是因为文档说“请注意,从操作系统将文件拖入浏览器时不会触发 dragstart 和 dragend 事件。” https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API

那么有没有一种方法可以让我从这些浏览器的文件上传窗口中拖动文件,而不必打开文件资源管理器?同样,我可以从 Chrome 和 Edge 的弹出窗口中拖放。

这是我的 HTML:

    Files: <input type="file" id="fileInput" name="files" multiple><br />

    <div id="selectedFiles"></div>

    <div class="picList">
        <div id="dropbox" style="border:1px solid black;height:500px;">
             Drop Here
        </div>
    </div>

这是我的 javascript:

dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
function dragenter(e) {
  e.stopPropagation();
  e.preventDefault();
}

function dragover(e) {
    e.stopPropagation();
    e.preventDefault();
}
function drop(e) {
    e.stopPropagation();
    e.preventDefault();

    var dt = e.dataTransfer;
    var files = dt.files;

    handleFiles(files);
}

有什么建议吗?

编辑:

这是我的 handleFiles 函数(dupCheck 是一个检查重复项的数组,存储文件是一个要上传的文件数组,我需要它是因为我希望用户能够通过删除预览图像和 HTML 来删除文件FileReader 是只读的,所以我不能直接从文件堆栈中删除单个图像。):

    function handleFiles(files) {
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        var imageType = /^image\//;

        if (!imageType.test(file.type)) {
            continue;
        }
        var img = document.createElement("img");
        img.classList.add("obj");
        img.file = file;
        $(img).addClass('selFile');
        $(img).attr('data-file', file.name);
        var A = [];
        for (var z = 0; z < dupCheck.length; z++) {
            A.push(dupCheck[z].name)
        }
        if (!A.includes(file.name)) {
            storedFiles.push(file);
            var _checker = { name: file.name };
            dupCheck.push(_checker);
            dropbox.appendChild(img);
            var reader = new FileReader();
            reader.onload = (function (aImg) { return function (e) { aImg.src = e.target.result; }; })(img);
            reader.readAsDataURL(file);
            A = [];
        };
    }
}

【问题讨论】:

标签: javascript jquery html drag-and-drop


【解决方案1】:

您可以使用两个 &lt;input type="file"&gt; 元素替换拖放事件。将选定的文件放在&lt;label&gt; 元素处,将&lt;input type="file"&gt; 控件设置为opacity 设置为0。

<!DOCTYPE html>
<html>

<head>
  <style type="text/css">
    #drop {
      opacity: 0;
    }
    #drop,
    label[for="drop"] {
      height: 500px;
      width: 500px;
    }
    label[for="drop"] {
      display: block;
      border: 1px solid black;
    }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js">
  </script>
  <script>
    $().ready(function() {
      var selectedFiles = $("#selectedFiles");
      
      function handleFiles(e) {
        var files = e.target.files;
        var input = this;

        for (var i = 0; i < files.length; i++) {
          (function(i, input) {
            var file = files[i];
            var figure = $("<figure></figure>", {
              append: $("<figcaption></figcaption>", {
                html: file.name
              })
            });

            var img = $("<img>").on("load", function() {
              selectedFiles.append(figure.prepend(img));
              input.value = null;
            });

            var reader = new FileReader();
            reader.onload = function(e) {
              img.attr("src", e.target.result);
            };
            reader.readAsDataURL(file);
          })(i, input);

        }
      }
      $(".fileInput").change(handleFiles);

    })
  </script>
</head>

<body>
  Files:
  <input type="file" 
         accept="image/*" 
         class="fileInput" 
         name="files0" 
         multiple="multiple" />
  <br />

  <div class="picList">

    <label for="drop" id="dropbox">
      Drop Here
      <input type="file" 
             accept="image/*" 
             id="drop" 
             class="fileInput" 
             name="files1" 
             multiple="multiple" />
    </label>
  </div>
  <div id="selectedFiles"></div>
</body>

  
</html>

【讨论】:

  • 正确。这给了我一些东西。谢谢!
  • 当我在 Chrome 中运行上面的代码 sn-p 时,它可以工作,但在 Firefox 中不行。我仍然在 Firefox 中得到带有斜线的圆圈。当我在 IE 11 中运行它时,我可以将图像拖出窗口,但它们不像在 Chrome 中那样附加。它通过单击而不是拖动来工作。尽管如此,我仍然非常重视这种方法!我一定是做错了什么。
  • @Pennywise 单击&lt;input type="file"&gt; 直到阅读您的问题之前,尚未考虑从资源管理器中拖动文件。不确定Choose File 或Browse 对话框是否预期用于拖放。您可以在 chromium 和 firefox 中将文件拖放到 &lt;input type="file"&gt; 元素本身。
  • 是的,这很痛苦。我想要这个功能的原因是因为从不擅长计算机的人的角度来看,它似乎对用户最友好。您单击浏览按钮,然后会弹出一个带有您的图片的窗口,因此想要从该窗口拖动图片而不是单独打开文件资源管理器似乎很自然。至少他们可以点击多个图像并附加。我想从弹出窗口中使用拖动功能,但也许那些浏览器不支持它?再次感谢您的帮助!我真的很感激:)
  • 我可能不得不尝试一下。我在 monzilla 上点击了社区表单,但到目前为止没有回复:support.mozilla.org/en-US/search/…
【解决方案2】:

所以我设法在 Firefox 中通过添加以下内容来解决这个问题:

e.dataTransfer.dropEffect = 'copy';

到我的拖动功能,现在看起来像这样:

    function dragover(e) {
    e.stopPropagation();
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
}

当我拖动到我的 Dropbox 上时,这样做会删除带有斜线的圆圈,这反过来又允许我进行放置以进行上传。

但是,这在 IE 11 中不起作用,所以如果有人有任何想法,我将不胜感激!

【讨论】:

  • 这对我不起作用。它对其他尝试过的人有用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 2013-12-21
  • 2016-12-29
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
相关资源
最近更新 更多