如何检测同一文件的输入类型=文件“更改”?

时间:2010-11-05 19:19:52

标签: jquery html events cross-browser

我想在用户选择文件时触发事件。对.change事件这样做,如果用户每次都更改文件,它就会起作用。

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

  1. 用户选择文件A.jpg(事件触发)
  2. 用户选择文件B.jpg(事件触发)
  3. 用户选择文件B.jpg(事件不会触发,我希望触发)
  4. 我该怎么做?

20 个答案:

答案 0 :(得分:67)

如果你已经尝试.attr("value", "")并且没有工作,请不要惊慌(就像我一样)

只需改为.val(""),并且可以正常使用

答案 1 :(得分:64)

你可以欺骗它。删除文件元素并将其添加到change事件的相同位置。它将擦除文件路径,使其每次都可以更改。

<强> Example on jsFiddle.

或者您只需使用.prop("value", "").val(""),请参阅this example on jsFiddle

  • jQuery 1.6+ prop
  • 早期版本attr

答案 2 :(得分:19)

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

102

答案 3 :(得分:16)

我通过清除onClick上的文件输入值然后将文件发布到了更改来实现此功能。这允许用户连续两次选择相同的文件,并且仍然将更改事件触发以发布到服务器。我的示例使用the jQuery form plugin

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

答案 4 :(得分:8)

每次用户单击字段时,使用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 = ''
}

答案 5 :(得分:7)

这项工作对我来说

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

答案 6 :(得分:3)

来自@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);
    }
}

onClick(event)在这里救了我:-)

答案 7 :(得分:3)

VueJs解决方案

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

答案 8 :(得分:2)

默认情况下,如果输入具有多个属性,则在选择文件后清除input元素的value属性。如果你不清理这个属性,那么&#34;改变&#34;如果选择同一文件,则不会触发事件。您可以使用multiple属性管理此行为。

<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>

Reference

答案 9 :(得分:1)

如果您不想使用jQuery

<form enctype='multipart/form-data'>
    <input onchange="alert(this.value); return false;" type='file'>
    <br>
    <input type='submit' value='Upload'>
</form>

它在Firefox中运行良好,但对于Chrome,您需要在警报后添加this.value=null;

答案 10 :(得分:1)

你不能在change点火(正确的行为,因为没有改变)。但是,您也可以绑定click ......虽然这可能会经常激发 但两者之间的中间地带并不多。

$("#fileID").bind("click change", function() {
  //do stuff
});

答案 11 :(得分:1)

可能最简单的方法是将值设置为空字符串。即使再次选择相同的文件,这也会强制其每次“更改”文件。

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

答案 12 :(得分:0)

根据被触发的事件类型,对于 React,您可能需要将解决方案调整为:

onClick={(event): string => (event.currentTarget.value = "")}

答案 13 :(得分:0)

最简单的方法是直接在change或input事件中将输入值设置为一个空字符串,无论如何该事件通常都是侦听的。

onFileInputChanged(event) {
     // todo: read the filenames and do the work
     
     // reset the value directly using the srcElement property from the event
     event.srcElement.value = ""
}

答案 14 :(得分:0)

为输入创建单击事件和更改事件。点击事件将清空输入,更改事件包含您要执行的代码。

因此,单击事件时,单击事件将为空(在打开选择文件窗口之前),因此,选择文件时,更改事件将始终触发。

$("#input").click(function() {
  $("#input").val("")
});

$("#input").change(function() {
  //Your code you want to execute!
});
<input id="input" type="file">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>

答案 15 :(得分:0)

相信我,它一定会对您有帮助!

fn != $3 || fn=="" {action}

希望这会对你们中的许多人有所帮助。

答案 16 :(得分:0)

因此,除非您存储每个文件并以编程方式进行比较,否则无法100%确保它们选择了相同的文件。

与文件交互的方式(用户“上传”文件时JS所做的事情)是https://www.cloudera.com/documentation/enterprise/5-6-x/topics/impala_analytic_functions.html#overHTML5 File API

JS FileReader

https://www.html5rocks.com/en/tutorials/file/dndfiles/

这些教程向您展示了文件上传时如何捕获和读取元数据(存储为js对象)。

创建一个触发“ onChange”的函数,该函数将读取->存储->将当前文件的元数据与先前的文件进行比较。然后,当选择了所需的文件时,您可以触发事件。

答案 17 :(得分:0)

我遇到了同样的问题,我在上面的解决方案中加了红色,但是他们没有得到任何很好的解释,说明真正发生了什么。

我写的这个解决方案https://jsfiddle.net/r2wjp6u8/并没有在DOM树中做很多更改,它只是更改了输入字段的值。从性能方面来说应该更好一些。

链接到小提琴:https://jsfiddle.net/r2wjp6u8/

<button id="btnSelectFile">Upload</button>

<!-- Not displaying the Inputfield because the design changes on each browser -->
<input type="file" id="fileInput" style="display: none;">
<p>
  Current File: <span id="currentFile"></span>
</p>
<hr>
<div class="log"></div>


<script>
// Get Logging Element
var log = document.querySelector('.log');

// Load the file input element.
var inputElement = document.getElementById('fileInput');
inputElement.addEventListener('change', currentFile);

// Add Click behavior to button
document.getElementById('btnSelectFile').addEventListener('click', selectFile);

function selectFile() {
  if (inputElement.files[0]) {
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    // Reset the Input Field
    log.innerHTML += '<p>Removing file: ' + inputElement.files[0].name + '</p>'
    inputElement.value = '';
    // Check how manyf iles are selected and display filename
    log.innerHTML += '<p>Total files: ' + inputElement.files.length + '</p>'
    log.innerHTML += '<hr>'
  }

  // Once we have a clean slide, open fiel select dialog.
  inputElement.click();
};

function currentFile() {
    // If Input Element has a file
  if (inputElement.files[0]) {
    document.getElementById('currentFile').innerHTML = inputElement.files[0].name;
  }
}

</scrip>

答案 18 :(得分:0)

您可以使用form.reset()清除文件输入的files列表。 这会将所有字段重置为默认值,但在许多情况下,您可能只使用输入类型=&#39;文件&#39;无论如何,以一种形式上传文件。 在此解决方案中,无需克隆元素并再次重新挂钩事件。

感谢philiplehmann

答案 19 :(得分:-1)

这是我发现对我有用的React-y way解决方案:

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