2014-05-02 42 views
9

我知道这个问题可能会重复,但因为现有的解决方案都不能帮助我发布我自己的问题。 我有一个拖放区域,我想检测拖动的项目是文件夹还是文件。在Chrome中我使用HTML5在Firefox中拖放文件夹检测。它甚至有可能吗?

for (var i = 0; i < nrOfFiles; i++) { 
      var entry = e.originalEvent.dataTransfer.items[i].webkitGetAsEntry(); 
      if (entry.isDirectory) { 
       //folder detection 
     } 

在Firefox中是无法使用上述溶液(WebKit),因此花费很多时间试图解决这个问题后实现这一点,我想出了以下解决方案(和失败)

  1. 我检查拖动的项目是否没有类型和大小如下,并在大多数情况下,它是按预期工作。从我读过的这是不高效和不成功的,因为有些文件可能没有文件扩展名,所以我尝试使用FileReader API将文件读为二进制字符串(readAsBinaryString)或readAsArrayBuffer,并在产品是不可读,但从不抛出异常。

      var files = e.originalEvent.dataTransfer.files; 
          for (var i = 0; i < nrOfFiles; i++) { 
          if (files[i].size === 0 && files[i].type==="") { 
    
           try{ 
            var reader = new FileReader(); 
            reader.readAsBinaryString(files[i]); 
           }catch(e){ 
            //folder detection ? 
           } 
    
          }} 
    
  2. 在下面的解决方案,我想使用mozGetDataAt作为对应的webkitGetAsEntry(???不是100%,这个请纠正我,如果我错了),但我得到一个安全异常。

      var entry = e.originalEvent.dataTransfer.mozGetDataAt("application/x-moz-file",i); 
          if (entry.isDirectory) { //not even reaching this statement. idk if isDirectory is applicable to entry 
           //folder detection? 
          } 
    

,异常是:

Permission denied for <http://localhost:8080> to create wrapper for object of class UnnamedClass 

实际上有没有办法在Firefox做到这一点?如果可能,我不想依赖第三方库或服务器端处理。任何建议意见将不胜感激。

感谢

中号

+0

它现在可能!看到我的回答:http://stackoverflow.com/a/33431704/195216 – dforce

回答

1

简单的回答你的问题是“否”,就没有办法使用在Firefox拖和下降来读取一个文件夹。

似乎还没有处理文件夹(尚)的HTML5标准。 Chrome处理文件夹的能力是他们内置到浏览器中的自定义内容(标准之外)。

目前没有办法使用HTML5/Javascript在Firefox(或IE相信)中进行文件夹拖放操作。 Mozilla's bugzilla上的这个特性有一个“bug”,它提到W3C目前已经停止为覆盖目录的文件系统API创建一个标准规范(虽然有这个editor's draft)。该Mozilla的错误仍处于新的状态,并没有出现分配/采取。

微软有this unofficial edge document的功能,这可能是有趣的,如果你也有关于在IE浏览器尝试这个问题。

8

它在Firefox 42是可能的和向上https://developer.mozilla.org/en-US/Firefox/Releases/42https://nightly.mozilla.org/):

https://jsfiddle.net/28g51fa8/3/

例如通过使用Drang'n'Drop事件:e.dataTransfer.getFilesAndDirectories();

,或者通过使用新的输入对话框,让用户的文件或文件夹上传之间进行选择:

<input id="dirinput" multiple="" directory="" type="file" /> 
<script> 
var dirinput = document.getElementById("dirinput"); 
dirinput.addEventListener("change", function (e) { 
    if ('getFilesAndDirectories' in this) { 
    this.getFilesAndDirectories().then(function(filesAndDirs) { 
     for (var i=0, arrSize=filesAndDirs.length; i < arrSize; i++) { 
      iterateFilesAndDirs(filesAndDirs[i]); 
     } 
    }); 
    } 
}, false); 
</script> 

相关Bugzillas:

https://bugzilla.mozilla.org/show_bug.cgi?id=1164310(实施MS针对新FileSystem API的缩减子集的建议)

https://bugzilla.mozilla.org/show_bug.cgi?id=1188880(发货目录选取和目录拖放)

https://bugzilla.mozilla.org/show_bug.cgi?id=1209924(目录:: GetFilesAndDirectories的支持过滤)

https://bugzilla.mozilla.org/show_bug.cgi?id=876480#c21(在Firefox 50发行,2016年11月)

代码部分地从: https://jwatt.org/blog/2015/09/14/directory-picking-and-drag-and-drophttps://archive.is/ZBEdF

可惜的是不在MS Edge目前为止: https://dev.modern.ie/platform/status/draganddropdirectories/

+0

对于Firefox,有人最终必须在“about:config”中创建一个新的布尔属性:dom.input.dirpicker = true – dforce

+0

应该指出的是,输入对话框方法目前在发布的版本中不起作用。 – whiskeyspider

+2

它已在FF50(2016年11月)发布:https://bugzilla.mozilla.org/show_bug.cgi?id=876480#c21 – thomasb

1

这里就是我做来解决这个问题:

var files = []; 

for(var i = 0; i < e.dataTransfer.files.length; i++){ 
    var ent = e.dataTransfer.files[i]; 
    if(ent.type) { 
     // has a mimetype, definitely a file 
     files.push(ent); 
    } else { 
     // no mimetype: might be an unknown file or a directory, check 
     try { 
      // attempt to access the first few bytes of the file, will throw an exception if a directory 
      new FileReader().readAsBinaryString(ent.slice(0, 5)); 
      // no exception, a file 
      files.push(ent); 
     } catch(e) { 
      // could not access contents, is a directory, skip 
     } 
    } 
} 

基本上是:

  • 如果拖拽和拖放项具有MIME类型,那么它是一个文件
  • 否则,尝试阅读条目内容
    • 只读取前5个字节(以避免意外地将大文件加载到内存中):ent.slice(0, 5)
    • 如果读取成功,那么它是一个文件
    • 如果读取失败,那么这是一个目录

享受!

+0

非常聪明。感谢那! – Jem

相关问题