JavaScript/HTML5/jQuery 拖放上传 - “未捕获的类型错误:无法读取未定义的属性‘文件’”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10813494/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 11:07:32  来源:igfitidea点击:

JavaScript/HTML5/jQuery Drag-And-Drop Upload - "Uncaught TypeError: Cannot read property 'files' of undefined"

javascriptjqueryhtmlfile-uploaddrag-and-drop

提问by svbnet

I will advise you prior that I have limited JavaScript experience.

我会事先告知您我的 JavaScript 经验有限。



目前,我有 JavaScript 代码:

$('#xhr-filebox').bind({
    "dragover": HandleDragEvent,
    "dragleave": HandleDragEvent,
    "drop": HandleDropEvent
});

function HandleDropEvent(e){
    var files = e.target.files || e.dataTransfer.files;
    UploadFile(files[0]);
}

(some code is omitted, but I will add more if you request)

(省略了一些代码,但如果您要求,我会添加更多)

...and the HTML:

...和 ​​HTML:

<div class="filebox" id="xhr-filebox">
    <p id="xhr-action">...or click me to pick one.</p>
</div>

However, when I drag a file into it, the Chrome JS console says this:

但是,当我将文件拖入其中时,Chrome JS 控制台会显示:

Uncaught TypeError: Cannot read property 'files' of undefined

未捕获的类型错误:无法读取未定义的属性“文件”

It can however get the FileList object when reading from a file input.

但是,它可以在从文件输入读取时获取 FileList 对象。

Curiously, when I log the event argument ( console.log(e) ), it logs it as f.event, whereas in a similar script of mine, it logs it as MouseEvent (screenshot: http://i.stack.imgur.com/3krcT.png)

奇怪的是,当我记录事件参数(console.log(e))时,它将它记录为 f.event,而在我的类似脚本中,它记录为 MouseEvent(截图:http://i.stack.imgur .com/3krcT.png)

Unlike the bind() function in jQuery, this uses the addEventListener() function of a DOM object returned by getElementById(), IE this is pure JavaScript. I have tried that method but nothing new happens.

与jQuery中的bind()函数不同,它使用getElementById()返回的DOM对象的addEventListener()函数,IE这是纯JavaScript。我试过这种方法,但没有新的发生。

回答by T.J. Crowder

If filesdoesn't exist on e.target, you're looking for a fileson e.dataTransfer — but if there's no dataTransferproperty on e(and there doesn't seem to be in your screenshot) you'll try to dereference undefined, resulting in this error.

如果fileson 不存在e.target,则您正在寻找fileson e.dataTransfer — 但如果没有dataTransferon 属性e(并且屏幕截图中似乎没有),您将尝试取消引用undefined,从而导致此错误。

I'd change the code to:

我将代码更改为:

function HandleDropEvent(e){
    var files = e.target.files || (e.dataTransfer && e.dataTransfer.files);
    if (files) {
        UploadFile(files[0]);
    }
    else {
        // Perhaps some kind of message here
    }
}

That way, if e.target.filesdoesn't exist and e.dataTransferalsodoesn't exist, you'll get filesbeing undefined, rather than an error.

这样,如果e.target.files不存在,e.dataTransfer并不存在,你会得到files作为undefined,而不是一个错误。



The event object that jQuery gives you is created and normalized by jQuery. Since we know e.dataTransferdoesn't exist on that event object (from your screenshot), my guess is that it's not one of the properties jQuery copies over from the original event object. That's okay, though, because jQuery gives us access to the original event via e.originalEvent. So I'd try:

jQuery 给你的事件对象是由 jQuery 创建和规范化的。由于我们知道e.dataTransfer该事件对象不存在(从您的屏幕截图),我的猜测是它不是 jQuery 从原始事件对象复制过来的属性之一。不过没关系,因为 jQuery 允许我们通过e.originalEvent. 所以我会尝试:

function HandleDropEvent(e){
    var dt = e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer);
    var files = e.target.files || (dt && dt.files);
    if (files) {
        UploadFile(files[0]);
    }
    else {
        // Perhaps some kind of message here
    }
}

That grabs filesfrom e.targetif that's where it is, or from the dataTransferobject wherever we find it (on e, or on e.originalEvent).

filese.target它所在的位置或dataTransfer我们找到它的任何地方(one或 on e.originalEvent)获取。

回答by Brad Bamford

I had been using the following code for the last several years:

过去几年我一直在使用以下代码:

var files = e.target.files || 
(e.dataTransfer ? e.dataTransfer.files : e.originalEvent.dataTransfer.files);

However, I've recently run into an issue using Chrome where e.target.files was there but with a length of 0 which caused files to be empty even though dataTransfer did have the dropped files.

但是,我最近在使用 Chrome 时遇到了一个问题,其中 e.target.files 存在但长度为 0,这导致文件为空,即使 dataTransfer 确实有删除的文件。

So, I've had to use a slightly different check:

所以,我不得不使用稍微不同的检查:

var files = e.target.files;
if (!files || files.length === 0)
    files = (e.dataTransfer ? e.dataTransfer.files : e.originalEvent.dataTransfer.files);

Hopefuly this may help someone else.

希望这可以帮助别人。