仅在上传区域上传一个文件

47

我正在使用dropzone.js实现拖放文件上传的解决方案。我希望只上传一个文件,如果我上传第二个文件,则应将第一个文件删除并上传第二个文件。有什么想法吗?

这是我的HTML:

<form class="dropzone dz-clickable" action="upload.php" enctype='multipart/form-data'>
  <i class="fa fa-cloud-upload element"></i>
  <div style="color:gray;">Drag and drop or click to upload image</div>
  <input type="hidden" name="filenameEmail" class="filenameEmail" value="">
  <input type="hidden" name="side" value="front">
</form>

我修改了 dropzone.js

maxFiles: 1

它只允许上传一个文件,但我无法删除先前上传的文件。请帮忙解决问题。谢谢。

8个回答

103

maxFiles: 1用于告诉dropzone只能上传一个文件。当上传的文件多于一个时,将调用函数maxfilesexceeded,第一个参数是超出限制的文件。

这里是一个简单的函数,可以删除第一个文件的预览并添加新的文件 :)

maxFiles:1,
init: function() {
      this.on("maxfilesexceeded", function(file) {
            this.removeAllFiles();
            this.addFile(file);
      });
}   

当我拖放文件时,第一个文件之后,文件的图像预览消失了,变成了灰色预览。 - Rachel
3
由于它会触发“error”事件,所以它并不完美。在跟踪错误时有问题。@darkbaby123适用于最新版本。 - Mike Casan Ballester
因为@darkbaby123的答案适用于更通用的情况(拖动文件或选择它们),所以被downvote了。 - rchavarria

32

我使用了事件maxfilesexceeded和方法addFile,但遇到了事件调用的无限循环。这可能是使用addFile方法的问题,因为我在官方网站和GitHub wiki中都没看到它被提到。最终我通过addedfile事件解决了这个问题。Dropzone.js版本是我撰写时的最新版本(4.3.0)。

init: function() {
  this.on('addedfile', function(file) {
    if (this.files.length > 1) {
      this.removeFile(this.files[0]);
    }
  });
}

谢谢您!@NeoNe的回答也很好,但是当您拖动一个文件时,它仍会上传两个文件。我尝试了您的方法,它可以双向上传 :) - Alyssa Reyes
2
这个对我有用。@NeoNe触发了错误事件。跟踪错误时不好。 - Mike Casan Ballester

19

maxFiles限制为1仍然允许在上传对话框中选择多个文件。要禁止在配置中选择多个图像,请指定以下init函数:

maxFiles:1,
init: function() {
    this.hiddenFileInput.removeAttribute('multiple');
}  

1
我尝试过这个,但对我没有用。我只有一个输入,我需要添加另一个(隐藏的)输入吗? - Andrew Fox
@AndrewFox 你解决了吗?我也无法使用。 - Milano
@MilanoSlesarik 很遗憾,我仍然遇到这个问题。 - Andrew Fox

2
 Dropzone.prototype.defaultOptions.init = function () {

                 this.hiddenFileInput.removeAttribute('multiple');
                 this.on("maxfilesexceeded", function (file) {
                     this.removeAllFiles();
                     this.addFile(file);
                 });
             };

这对我来说很有效。


0

这对我有用

const dropzoneInput = document.querySelectorAll('.dz-hidden-input')
for (const input of dropzoneInput) {
    if (input.getAttribute('multiple')) {
        input.removeAttribute('multiple')
    }
}

这段代码的作用是验证 dropzone 输入框是否具有 multiple 属性,如果有,则移除 id。

注意:类名.dz-hidden-input可能因情况而异。


0
很多解决方案都可以接受两个文件,但是上传哪个文件有点随机。更好的方式是通知用户。
init: function () {
    this.on('addedfile', function () {
        if (this.files.length > 1) {
            this.removeAllFiles();
            alert('Drop only one file');
        }
    });
}

注意:这里不需要使用maxFiles,因为我们不使用maxfilesexceeded。只需相应地设置this.files.length > 1即可。

0

在init函数中,这两个解决方案的组合对我起到了作用:

        this.on("addedfile", function (file) {
            if (this.files.length > 1) {
                this.removeAllFiles()
                this.addFile(file);
            }
        });

-1

这些解决方案都对我没用。

maxfilesexceeded事件被调用得太晚了,即在尝试添加文件之后。

其他使用this.removeFile(this.files[0]);的解决方案导致"Uncaught TypeError: Cannot read property 'removeChild' of null"或无限循环。

解决方法:-

maxFiles: 2,
init: function () {

    this.on("addedfile", function (file) {
        if (this.files.length > 1) {
            this.files = this.files.slice(1, 2);                        
        }
    });

}

使用 dz-clickable(文件选择器按钮)和拖放时有效。


请注意,maxFiles: 2 允许多个文件选择。这会给移动设备带来糟糕的用户体验和误导。请参考 @darkbaby123 的回答。 - Mike Casan Ballester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接