如何检测同一文件的输入类型=文件“更改”?
Posted
技术标签:
【中文标题】如何检测同一文件的输入类型=文件“更改”?【英文标题】:How to detect input type=file "change" for the same file? 【发布时间】:2011-05-05 18:55:15 【问题描述】:我想在用户选择文件时触发一个事件。如果用户每次都更改文件,则使用 .change
事件这样做。
但如果用户再次选择相同的文件,我想触发该事件。
-
用户选择文件
A.jpg
(事件触发)
用户选择文件B.jpg
(事件触发)
用户选择文件B.jpg
(事件不触发,我希望它触发)
我该怎么做?
【问题讨论】:
【参考方案1】:根据被触发的事件类型,对于 React,您可能需要将解决方案调整为:
onClick=(event): string => (event.currentTarget.value = "")
【讨论】:
【参考方案2】:最简单的方法是直接在 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 = ""
【讨论】:
【参考方案3】:这是我发现对我有用的 React-y 方式解决方案:
onClick=event => event.target.value = null
【讨论】:
谢谢!修改你对 @click="(e) => e.target.value = null" 的回答给了我一个 Vue 解决方案。【参考方案4】:为输入创建一个点击事件和一个更改事件。 click事件清空输入,change事件包含你要执行的代码。
因此,当您单击输入按钮时(在选择文件窗口打开之前),单击事件将为空,因此当您选择文件时始终会触发更改事件。
$("#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>
【讨论】:
【参考方案5】:你可以欺骗它。删除文件元素并将其添加到 change
事件的相同位置。它会擦除文件路径,使其每次都可以更改。
Example on jsFiddle.
或者您可以简单地使用.prop("value", "")
,参见this example on jsFiddle。
prop
早期版本attr
【讨论】:
@Pekka:不完全是。但他只能适应它。假设他需要发布文件。在发布之后,他可以调用一个 js 函数,该函数将删除和添加新的文件选择器。这是可行的。 请注意,当您使用.attr("value", "")
或 .val("")
(如下面的 @wagner-leonardi 建议的那样)时,Internet Explorer 将触发更改事件,而 chrome 则不会
因为 "value" 是一个属性而不是输入的属性,所以推荐的 jQuery 用法是.prop("value", "")
【参考方案6】:
您可以做的最简单的事情可能是将值设置为空字符串。即使再次选择相同的文件,这也会强制它每次“更改”文件。
<input type="file" value="" />
【讨论】:
这应该是公认的答案 - 它根本不需要 javascript。 @AlexanderMihailov 当用户实际选择文件时,它仍然如此。【参考方案7】:每次用户点击字段时,使用 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 = ''
【讨论】:
【参考方案8】:VueJs 解决方案
<input
type="file"
style="display: none;"
ref="fileInput"
accept="*"
@change="onFilePicked"
@click="$refs.fileInput.value=null"
>
【讨论】:
感谢您提供这个变体答案【参考方案9】:灵感来自@braitsch,我在 AngularJS2 input-file-component
987654321@ 中使用了以下内容
<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)
救了我 :-)
【讨论】:
【参考方案10】:相信我,它一定会对你有所帮助!
// there I have called two `onchange event functions` due to some different scenario processing.
<input type="file" class="selectImagesHandlerDialog"
name="selectImagesHandlerDialog"
onclick="this.value=null;" accept="image/x-png,image/gif,image/jpeg" multiple
onchange="delegateMultipleFilesSelectionAndOpen(event); disposeMultipleFilesSelections(this);" />
// delegating multiple files select and open
var delegateMultipleFilesSelectionAndOpen = function (evt)
if (!evt.target.files) return;
var selectedPhotos = evt.target.files;
// some continuous source
;
// explicitly removing file input value memory cache
var disposeMultipleFilesSelections = function ()
this.val = null;
;
希望这对你们中的许多人有所帮助。
【讨论】:
【参考方案11】:因此,除非您存储每个文件并以编程方式比较它们,否则无法 100% 确保他们选择相同的文件。
您与文件交互的方式(当用户“上传”文件时 JS 所做的)是HTML5 File API 和JS FileReader。
https://www.html5rocks.com/en/tutorials/file/dndfiles/
https://scotch.io/tutorials/use-the-html5-file-api-to-work-with-files-locally-in-the-browser
这些教程向您展示了如何在文件上传时捕获和读取元数据(存储为 js 对象)。
创建一个触发“onChange”的函数,该函数将读取->存储->将当前文件的元数据与以前的文件进行比较。然后您可以在选择所需文件时触发您的事件。
【讨论】:
【参考方案12】:我遇到了同样的问题,我通过了上面的解决方案,但他们没有得到任何很好的解释到底发生了什么。
我写的这个解决方案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>
【讨论】:
【参考方案13】:默认情况下,如果输入具有多个属性,则在选择文件后会清除输入元素的 value 属性。如果您不清除此属性,则如果您选择相同的文件,则不会触发“更改”事件。您可以使用multiple
属性管理此行为。
<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>
Reference
【讨论】:
【参考方案14】:您可以简单地将每次用户单击控件时的文件路径设置为null。现在,即使用户选择了同一个文件,onchange 事件也会被触发。
<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />
【讨论】:
我需要这样的解决方案。它真的很短,可以完成工作。 Mariusz Wiazowski 的想法很好。 其他解决方案是在输入标签更改时更改值。但是我们不希望在选择文件后更改该值。 酷,比在 dom 中再次删除和添加元素要好得多,谢谢【参考方案15】:您可以使用form.reset()
清除文件输入的files
列表。
这会将所有字段重置为默认值,但在许多情况下,您可能只在表单中使用输入 type='file' 来上传文件。
在此解决方案中,无需克隆元素并再次重新挂钩事件。
感谢philiplehmann
【讨论】:
【参考方案16】:如果你不想使用 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;
。
【讨论】:
【参考方案17】:如果您尝试过.attr("value", "")
并没有成功,请不要惊慌(就像我一样)
改用.val("")
,就可以了
【讨论】:
【参考方案18】:这对我有用
<input type="file" onchange="function();this.value=null;return false;">
【讨论】:
我猜你的意思是 function() this.value = null;返回假; 【参考方案19】:我通过清除文件输入值 onClick 然后发布文件 onChange 来实现此功能。这允许用户连续两次选择同一个文件,并且仍然让更改事件触发以发布到服务器。我的示例使用the jQuery form plugin。
$('input[type=file]').click(function()
$(this).attr("value", "");
)
$('input[type=file]').change(function()
$('#my-form').ajaxSubmit(options);
)
【讨论】:
onClick
在onChange
之前触发,所以这种方法对我来说很有效。
对于 jQuery 2.2.4,我必须使用 $(this).val("");
。【参考方案20】:
你不能在这里触发change
(正确的行为,因为没有任何改变)。但是,您也可以绑定 click
...虽然这可能会经常触发 ...不过两者之间没有太多的中间地带。
$("#fileID").bind("click change", function()
//do stuff
);
【讨论】:
看来你只是在重复他的话,.click()
不是“重新选择时触发”。
@BrunoLM - 不,这不是......但我认为你阅读了我说你不能这样做的部分,click
尽可能接近。以上是关于如何检测同一文件的输入类型=文件“更改”?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jest/Enzyme 在 React 中测试文件类型输入的更改处理程序?
如何在表单的输入类型=“文件”中添加图像并将它们都提交到同一个表单后生成缩略图