繁体   English   中英

清除以前拖动的文件条目?

[英]Clearing previous dragged file entries?

我有以下脚本要用于上传文件。 一切正常,但是我很难找出为什么每次上载新文件时都会显示以前拖动的文件。 由于程序的异步性质,因此在调试时遇到了麻烦。

小提琴:

http://jsfiddle.net/tekky/PYTBw/

码:

var dndbox = $(".dndbox")[0];

dndbox.addEventListener("dragenter", function(e) {
    e.stopPropagation();
    e.preventDefault();
},false);

dndbox.addEventListener("dragover", function(e) {
    e.stopPropagation();
    e.preventDefault();
},false);

dndbox.addEventListener("drop", function(e) {
    e.stopPropagation();
    e.preventDefault();

    var itemList = e.dataTransfer.items;

    var fp = [];

    var traverse = function(entry)
        {
            if (entry.isFile) {
                entry.file(function(file) {
                    var filepromise = new Promise(function(res, rej) {
                        res(file);
                    });
                    fp.push(filepromise);
                });
            } else if (entry.isDirectory){
                var dR = entry.createReader();
                dR.readEntries(function(entries) {
                    for(var i = 0; i < entries.length; i++)
                    {
                        traverse(entries[i]);
                    }
                });
            }
        }

        var collection = [];
        for(var i = 0; i < itemList.length; i++) {
            var e = itemList[i].webkitGetAsEntry();
            var tp = new Promise(function(r, rj) {
                traverse(e);
                r(fp);
            });
            collection.push(tp);
        }

        Promise.all(collection).then(function(ff) {
            $(".prompt").show();
            $(".prompt").on("click", function() {
                $(this).hide();
                ff.forEach(function(pa) {
                    pa.forEach(function(p){
                        p.then(function(f)
                        {
                            console.log(f);
                        });

                    });
                });
            });
        });
},false);

每次上传新文件时,也会显示以前拖动的文件。

这不是由于traverse的异步性质,与诺言没有太大关系。 这是由于这种结构:

// left away some irrelevant callbacks
dndbox.addEventListener("drop", function(e) {
    var fp = [];
    // add entries to fp
    $(".prompt").on("click", function() {
        console.log(fp);
    });
}, false);

如您所见,每次删除内容时,您都会创建一个新列表,并将侦听器添加到(相同)元素中, 从现在开始的每次单击都会记录该列表。 要解决该问题,您可以:

  • 仅使用一个在发生新的drop事件时将被覆盖的全局列表
  • 为每个要记录的列表创建一个新的.prompt元素
  • 触发监听器后将其卸载,以免再次触发。 您可以为此使用jQuery .one()方法

除此之外,您使用Promises非常奇怪(更不用说错了)。 collection是一个承诺列表,这些承诺将立即通过仍然为空的fp数组解决。 您只有幸运的是,在触发click回调时可以读取所有文件。 不过,您获得的每个pa === fp ,因此您将fp每个项目记录的时间与itemList时间一样长。

看看在node.js中了解递归函数的promise, 是否有一个示例,使用带有节点的原始Q promise库以异步方式递归遍历目录? 有关如何正确执行的操作。 在您的情况下,

function traverse(entries)
    var collection = [];
    for (var i=0; i<entries.length; i++) {
        var entry = entries[i];
        if (entry.isFile) {
            collection.push(new Promise(function(res, rej) {
                entry.file(res);
            }));
        } else if (entry.isDirectory){
            collection.push(new Promise(function(res, rej) {
                var dR = entry.createReader();
                dR.readEntries(res);
            }).then(traverse));
        }
    }
    return Promise.all(collection).then(function(results) { // flatten
        return [].concat.apply([], results);
    });
}

var entries = [];
for(var i = 0; i < itemList.length; i++)
    entries[i] = itemList[i].webkitGetAsEntry();

traverse(entries).then(function(fp) {
    $(".prompt").show().one("click", function() {
        $(this).hide();
        fp.forEach(console.log, console);
    });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM