我的问题的关键是我需要异步使用datatransferitemlist,这与规范中描述的功能不一致,规范表示一旦事件结束,您将无法访问dataTransfer.items集合。
我正在使用异步的zip.js和HTML5 DnD API。在异步的zip.createWriter/writer.add操作完成之前,ondrop事件就已经结束了。我可以想到四种解决方法,但我不知道如何实现它们,希望得到一些建议。
罪犯案件如下。下面更详细地描述了我的问题和想法。https://bugs.chromium.org/p/chromium/issues/detail?id=137231 http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-data-store
drophandler: function(event) {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
zip.workerScriptsPath = "../bower_components/zip.js/WebContent/";
zip.useWebWorkers = false; // Disabled because it just makes life more complicated
// Check if files contains just a zip
if (event.dataTransfer.files[0].name.match(/(?:\.([^.]+))?$/) == 'zip') {
var reader = new FileReader();
that = this;
reader.onload = function(e) {
that.fire('zipuploaded', e.target.result.split(',')[1]);
}
reader.readAsDataURL(event.dataTransfer.files[0]);
// Rev up that in browser zipping
} else {
var that = this;
var items = event.dataTransfer.items;
// Async operation, execution falls through from here
zip.createWriter(new zip.Data64URIWriter(), function(writer) {
(function traverse(list, path, i, depth) {
return new Promise(function(resolve, reject) {
var item;
if (depth == 0) {
if (i == list.length) {
writer.close(function(uri) {
that.fire('zipuploaded', uri.split(',')[1]); // Just the base64, please
fulfill(1);
return;
});
} else {
console.log(i);
console.log(list);
var item = list[i].webkitGetAsEntry();
}
} else {
if (i == list.length) {
resolve(0);
return;
} else {
item = list[i];
}
}
if (item.isFile) {
item.file(function(file) {
// Zipping operations done asynchronously, it'll fail by roughly the second operation
writer.add(path + file.name, zip.BlobReader(file), function() {
traverse(list, path, i + 1, depth).then(resolve(0)); // Next item
});
});
} else if (item.isDirectory) {
var dirReader = item.createDirReader();
dirReader.readEntries(function(entries) {
// Operate on child folder then the next item at this level
traverse(entries, path + item.name + "/", 0, depth + 1).then(function() {
traverse(list, path, i + 1, depth).then(resolve(0));
});
});
}
});
})(items, "", 0, 0); // Begin with datatransferitemlist, 0th element, depth 0
});
this.$.uploadarea.classList.remove('highlightdrag');
}
// When we exit it kills the event.dataTransfer.items
},
我正在使用异步的zip.js和HTML5 DnD API。在异步的zip.createWriter/writer.add操作完成之前,ondrop事件就已经结束了。我可以想到四种解决方法,但我不知道如何实现它们,希望得到一些建议。
- 阻塞直到createWriter完成。(阻塞javascript?不好)
- 防止ondrop锁定dataTransfer.items(这似乎是为了安全起见,所以不太可能)
- 先同步复制dataTransfer.items的内容(可能非常慢)
- 全部同步进行(我认为zip.js不允许这样做,JsZip允许,但由于其在处理大文件集方面有自己的限制,我放弃了它)
traverse(list, path, i + 1, depth).then(resolve(0))
立即调用了resolve
函数,而不是引用它。不确定预期结果是什么?将所有丢失的文件添加到单个.zip
文件夹中吗? - guest271314