如何检测同一文件的input type=file "change"?

214

我想在用户选择文件时触发一个事件。如果用户每次更改文件,则使用.change事件即可运行。

但是,如果用户再次选择相同的文件,我想要触发该事件。

  1. 用户选择文件A.jpg(事件触发)
  2. 用户选择文件B.jpg(事件触发)
  3. 用户选择文件B.jpg(事件不会触发,我希望它触发)

我该怎么做?


这个回答解决了你的问题吗?选择相同文件后,HTML输入文件选择事件不触发 - undefined
23个回答

135

每次用户单击控件时,您可以简单地将文件路径设置为null。现在,即使用户选择相同的文件,也会触发onchange事件。

<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />

7
我需要像这样的解决方案。它非常简洁,能够完成工作。Mariusz Wiazowski想得真好。 - Jay Dharmendra Solanki
另一种解决方案是在输入标签更改时更改值。但是我们不希望在选择文件后更改该值。 - songgeb
3
很酷,比在DOM中删除和添加元素要好得多,谢谢。 - David Dal Busco
1
我对这个解决方案的问题在于,如果用户随后点击取消,那么至少在Chrome中不会触发更改事件。 - Cory Harper

101

你可以骗过它。移除文件元素并在change事件中再次添加它。这将清除文件路径,使其每次都可以更改。

jsFiddle上的示例。

或者你可以简单地使用.prop("value", ""),参见jsFiddle上的此示例

  • jQuery 1.6+使用prop
  • 早期版本使用attr

@Pekka:不完全是这样。但他可以适应它。假设他需要发布文件。在发布后,他可以调用一个js函数来删除并添加新的文件选择器。这是可行的。 - BrunoLM
4
请注意,当您使用.attr("value", "").val("")(如下所建议的@wagner-leonardi)时,Internet Explorer会触发change事件,而Chrome不会。 - fadomire
5
由于"value" 是一个属性而不是 input 的属性(attribute),因此建议使用 jQuery 的 .prop("value", "") 来设置。 - Roger Barreto

78

如果你尝试了.attr("value", "")但是没有起作用,不要惊慌(就像我一样)

只需使用.val("")代替,就可以正常工作了


63

使用 onClick 事件在用户每次点击输入框时清除目标输入框的值。这可以确保 onChange 事件也将为相同的文件触发。尝试过对我很有用 :)

onInputClick = (event) => {
    event.target.value = ''
}

<input type="file" onChange={onFileChanged} onClick={onInputClick} />

使用 TypeScript

onInputClick = ( event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
    const element = event.target as HTMLInputElement
    element.value = ''
}

27

我找到了一种React-y的解决方案,对我很有效:

onClick={event => event.target.value = null}


2
谢谢!将您的答案修改为@click="(e) => e.target.value = null",让我得到了一个Vue解决方案。 - anniex
真棒,简单明了! - Michael

19

我通过在点击时清除文件输入的值,然后在更改时发布文件来使其工作。这允许用户连续两次选择同一文件,并仍然触发更改事件以将其发布到服务器。我的示例使用jQuery表单插件

$('input[type=file]').click(function(){
    $(this).attr("value", "");
})  
$('input[type=file]').change(function(){
    $('#my-form').ajaxSubmit(options);      
})

onClickonChange 之前触发,所以这个方法对我非常有效。 - iplus26
我不得不在jQuery 2.2.4中使用$(this).val(""); - JohnK

15

VueJs 解决方案

<input
                type="file"
                style="display: none;"
                ref="fileInput"
                accept="*"
                @change="onFilePicked"
                @click="$refs.fileInput.value=null"
>

1
感谢您提供这个不同的答案。 - Coisox

11

这对我有效

<input type="file" onchange="function();this.value=null;return false;">

1
我猜你的意思是这样的 function() { this.value = null; return false; }。 - Jacek Pietal

9

最简单的方法是将值设置为空字符串。这会强制它每次都“更改”文件,即使选择的仍然是同一个文件。

<input type="file" value="" />


这应该是被接受的答案 - 它完全不需要 JavaScript。 - Alexander Mihailov
1
@AlexanderMihailov 当用户实际选择文件时,它仍然会发生。 - user13944038

7

受 @braitsch 的启发,我在我的 AngularJS2 input-file-component 中使用了以下代码:

<input id="file" onclick="onClick($event) onchange="onChange($event)" type="file" accept="*/*" />

export class InputFile {

    @Input()
    file:File|Blob;

    @Output()
    fileChange = new EventEmitter();

    onClick(event) {
        event.target.value=''
    }
    onChange(e){
        let files  = e.target.files;
        if(files.length){
            this.file = files[0];
        }
        else { this.file = null}
        this.fileChange.emit(this.file);
    }
}

Here the onClick(event) rescued me :-)


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