我有一个放置区域,用于检测拖动的项目是文件夹还是文件。在chrome中,我通过使用实现了这一点
for (var i = 0; i < nrOfFiles; i++) {
var entry = e.originalEvent.dataTransfer.items[i].webkitGetAsEntry();
if (entry.isDirectory) {
//folder detection
}
在firefox中,不可能使用上述解决方案(webkit(,在花了很多小时试图解决这个问题后,我想出了以下解决方案(但失败了(
我检查拖动的项目是否没有类型和大小,如下所示,在大多数情况下,它都按预期工作。从我所读到的内容来看,这并不有效,也不总是成功的,因为有些文件可能没有文件扩展名,所以我尝试用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 ? } }}
在下面的解决方案中,我试图使用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? }
例外情况是:
的权限被拒绝http://localhost:8080为类UnnamedClass 的对象创建包装
在firefox中真的有办法做到这一点吗?如果可能的话,我不想依赖第三方库或服务器端处理。如有任何建议和意见,我们将不胜感激。
在Firefox 42及更高版本中是可能的(https://developer.mozilla.org/en-US/Firefox/Releases/42,https://nightly.mozilla.org/):
https://jsfiddle.net/28g51fa8/3/
使用拖放事件: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(2016年11月在Firefox 50中发布(
部分代码来自:https://jwatt.org/blog/2015/09/14/directory-picking-and-drag-and-drop(https://archive.is/ZBEdF)
不幸的是,到目前为止还没有进入MS Edge:https://dev.modern.ie/platform/status/draganddropdirectories/更新:edge现在似乎得到了支持。
以下是我为解决这个问题所做的:
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 )
- 如果读取成功,则它是一个文件
- 如果读取失败,则这是一个目录
- 只读取前5个字节(以避免意外将大文件加载到内存中(:
享受吧!
问题的简单答案是"否"在Firefox中无法使用拖放方式读取文件夹。
似乎还没有一个HTML5标准来处理文件夹。Chrome处理文件夹的能力是他们在浏览器中内置的自定义功能(标准之外(。
目前还没有办法在Firefox(或者我相信的IE(中使用HTML5/Javascript进行文件夹拖放。Mozilla的bugzilla上有一个"bug",它提到W3C目前已经停止为文件系统API创建涵盖目录的标准规范(尽管有这个编辑器的草案(。Mozilla漏洞仍然处于"新建"状态,并且没有显示为已分配/已获取。
微软有这个关于该功能的非官方边缘文档,如果你对在IE中尝试这个功能也有疑问,这可能会很有趣。