【发布时间】:2011-05-05 18:55:15
【问题描述】:
我想在用户选择文件时触发一个事件。如果用户每次都更改文件,则使用 .change 事件这样做。
但如果用户再次选择相同的文件,我想触发该事件。
- 用户选择文件
A.jpg(事件触发) - 用户选择文件
B.jpg(事件触发) - 用户选择文件
B.jpg(事件不触发,我希望它触发)
我该怎么做?
【问题讨论】:
标签: jquery html events cross-browser
我想在用户选择文件时触发一个事件。如果用户每次都更改文件,则使用 .change 事件这样做。
但如果用户再次选择相同的文件,我想触发该事件。
A.jpg(事件触发)B.jpg(事件触发)B.jpg(事件不触发,我希望它触发)我该怎么做?
【问题讨论】:
标签: jquery html events cross-browser
根据被触发的事件类型,对于 React,您可能需要将解决方案调整为:
onClick={(event): string => (event.currentTarget.value = "")}
【讨论】:
最简单的方法是直接在 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 = ""
}
【讨论】:
这是我发现对我有用的 React-y 方式解决方案:
onClick={event => event.target.value = null}
【讨论】:
为输入创建一个点击事件和一个更改事件。 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>
【讨论】:
你可以欺骗它。删除文件元素并将其添加到 change 事件的相同位置。它会擦除文件路径,使其每次都可以更改。
或者您可以简单地使用.prop("value", ""),参见this example on jsFiddle。
prop
attr
【讨论】:
.attr("value", "") 或 .val("")(如下面的 @wagner-leonardi 建议的那样)时,Internet Explorer 将触发更改事件,而 chrome 则不会
.prop("value", "")
您可以做的最简单的事情可能是将值设置为空字符串。即使再次选择相同的文件,这也会强制它每次“更改”文件。
<input type="file" value="" />
【讨论】:
每次用户点击字段时,使用 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 = ''
}
【讨论】:
VueJs 解决方案
<input
type="file"
style="display: none;"
ref="fileInput"
accept="*"
@change="onFilePicked"
@click="$refs.fileInput.value=null"
>
【讨论】:
灵感来自@braitsch,我在 AngularJS2 input-file-component987654321@ 中使用了以下内容
<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) 救了我 :-)
【讨论】:
相信我,它一定会对你有所帮助!
// 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;
};
希望这对你们中的许多人有所帮助。
【讨论】:
因此,除非您存储每个文件并以编程方式比较它们,否则无法 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”的函数,该函数将读取->存储->将当前文件的元数据与以前的文件进行比较。然后您可以在选择所需文件时触发您的事件。
【讨论】:
我遇到了同样的问题,我通过了上面的解决方案,但他们没有得到任何很好的解释到底发生了什么。
我写的这个解决方案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>
【讨论】:
默认情况下,如果输入具有多个属性,则在选择文件后会清除输入元素的 value 属性。如果您不清除此属性,则如果您选择相同的文件,则不会触发“更改”事件。您可以使用multiple 属性管理此行为。
<!-- will be cleared -->
<input type="file" onchange="yourFunction()" multiple/>
<!-- won't be cleared -->
<input type="file" onchange="yourFunction()"/>
【讨论】:
您可以简单地将每次用户单击控件时的文件路径设置为null。现在,即使用户选择了同一个文件,onchange 事件也会被触发。
<input id="file" onchange="file_changed(this)" onclick="this.value=null;" type="file" accept="*/*" />
【讨论】:
您可以使用form.reset() 清除文件输入的files 列表。
这会将所有字段重置为默认值,但在许多情况下,您可能只在表单中使用输入 type='file' 来上传文件。
在此解决方案中,无需克隆元素并再次重新挂钩事件。
【讨论】:
如果你不想使用 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;。
【讨论】:
如果您尝试过.attr("value", "") 并没有成功,请不要惊慌(就像我一样)
改用.val(""),就可以了
【讨论】:
这对我有用
<input type="file" onchange="function();this.value=null;return false;">
【讨论】:
我通过清除文件输入值 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 之前触发,所以这种方法对我来说很有效。
$(this).val("");。
你不能在这里触发change(正确的行为,因为没有任何改变)。但是,您也可以绑定 click...虽然这可能会经常触发 ...不过两者之间没有太多的中间地带。
$("#fileID").bind("click change", function() {
//do stuff
});
【讨论】:
.click() 不是“重新选择时触发”。
click 尽可能接近。