@bornkiller
2014-08-30T15:33:52.000000Z
字数 3358
阅读 3765
javascript
文件拖动上传,对于个别应用场景十分有效,实现起来也并不难。参见
“浏览器图片预览 --http://blog.segmentfault.com/bornkiller/1190000000428572"。
现在更进一步,做到文件夹拖动。以下内容全基于chrome 36 版本测试成功。
API 被分为以下不同的主题:
读取和处理文件:File/Blob、FileList、FileReader
创建和写入:BlobBuilder、FileWriter
目录和文件系统访问:DirectoryReader、FileEntry/DirectoryEntry
var requestFileSystem = window.requestFileSystem ?window.requestFileSystem:window.webkitRequestFileSystem;// success 回调函数var onInitFS = function(fs) {};// error 回调函数var onInitFE = function(fe) {};requestFileSystem(window.TEMPORARY, 10*1024*1024, onInitFS, onInitError);
window.addEventListener('load', function(evt) {document.addEventListener('drop', prevent);document.addEventListener('dragenter', prevent);document.addEventListener('dragleave', prevent);document.addEventListener('dragover', prevent);});function prevent(e){e.stopPropagation();e.preventDefault();}
document.addEventListener('drop',entryResolve);function entryResolve(e){var items = e.dataTransfer.items;// 多文件/文件夹拖动时,items.length即为拖入文件/文件夹数量var itemsCount = items.length;// 获取文件/文件夹Entry对象var entries = [];for (var i=0; i<itemsCount; i++) {entries.push(items[i].webkitGetAsEntry());}}
每个Entry对象具备isDirectory, isFile属性,判定目标为文件或是文件夹。具体接口可以自行查阅
entries.forEach(function(entry, key) {if(entry.isDirectory && !entry.isFile) {// entry is DirectoryEntry here}else if(!entry.isDirectory && entry.isFile) {// entry is FileEntry here}else{return false;}})
getFile()方法getDirectory()方法removeRecursively()方法
function readDir(directoryEntry, readDirCallback) {// 判定参数类型是否匹配if (!directoryEntry.isDirectory || !typeof value === 'function') {return false;}var fileEntriesContainer = [];// 创建目录遍历器 dirReadervar dirReader = directoryEntry.createReader();// 遍历目录,由于无法一次性返回全部,所以需要递归调用,直到返回结果为空,执行回调函数。var readEntries = function() {dirReader.readEntries (function(results) {if (!results.length) {readDirCallback(fileEntriesContainer);} else {fileEntriesContainer = fileEntriesContainer.concat(toArray(results));readEntries();}}, errorHandler);};readEntries();}
function readDirectoryEntry(directoryEntry) {return Q.Promise(function(resolve, reject) {if(directoryEntry.isDirectory) {resolve(true);} else {reject(false);}}).then(function() {return readDirectory(directoryEntry);})};// 返回值为promise,传递值为目录下所有的entry对象组成的数组。function readDirectory(directoryEntry) {var defer = Q.defer();var fileEntriesContainer = [];var dirReader = directoryEntry.createReader();// Call the reader.readEntries() until no more results are returned.var readEntries = function() {dirReader.readEntries(function(results) {if (!results.length) {defer.resolve(fileEntriesContainer);} else {fileEntriesContainer = fileEntriesContainer.concat(toArray(results));readEntries();}}, function(err) {defer.reject(err.message);});};readEntries();return defer.promise;}
// 通过file函数即可获得File 对象// File 对象处理请自行参阅 FileReaderentry.file(function(file){var fileReader = new FileReader();fileReader.readAsText(file);fileReader.addEventListener('load', function(){console.log(this.result);})})
QQ : 491229492
注明交流即可