javascript 输入文件的第二次使用不再触发 onchange
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19643265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Second use of input file doesn't trigger onchange anymore
提问by ether
I have a picture upload button that automatically uploads the file when selected from the browse window.
Nonetheless, it doesn't work the second time around and that is because the onChange event is not triggered. Why is that so?
我有一个图片上传按钮,可以在从浏览窗口中选择时自动上传文件。
尽管如此,它第二次不起作用,这是因为没有触发 onChange 事件。为什么呢?
Here is a use case:
1. On click of the button, I call uploadMessagePicture(), which opens the browse window.
2. When the user has selected a picture, a onChange event is detected which triggers the ajaxFileUpload() and shows the photo editor area.
3. When the upload is complete, a preview of the image is shown.
4. The user deletes the picture by calling deleteMessageImage() (which also clears the fields and hides the photo editor).
5. The user tries to upload another picture.
这是一个用例:
1. 单击按钮时,我调用uploadMessagePicture(),这会打开浏览窗口。
2. 当用户选择一张图片时,会检测到一个 onChange 事件,它会触发 ajaxFileUpload() 并显示照片编辑器区域。
3. 上传完成后,将显示图像预览。4. 用户通过调用deleteMessageImage() 删除图片(同时清除字段并隐藏照片编辑器)。
5. 用户尝试上传另一张图片。
At this point, the browse window appears, but when I select a picture, the onChange event is not triggered so nothing happens... (Also, it doesn't seem like the filename is even transfered to the input' value field.)
I'm on Firefox 23.0.1
此时,浏览窗口出现,但是当我选择一张图片时,没有触发 onChange 事件,所以什么也没有发生......(此外,似乎文件名甚至没有传输到输入的值字段。)
我使用的是 Firefox 23.0.1
Here is the HTML:
这是 HTML:
<a class="im-photo-btn" href="javascript:;" onclick="javascript:uploadMessagePicture();"><i class="icon-join-photo"></i></a>
<div class="editor-photoarea" id="editor-photoarea" style="display:none;">
<input name="image_message_file" type="hidden" id="image_message_file" value="" />
<div id="image_message_upload">
<input name="image-message" type="file" id="image-message" style="display:none; visibility:hidden;" />
<!-- hide it and trigger it from the photo btn (need both display:none + visibility:hiden for browser compatibility) -->
</div>
<div class="loading" id="image_message_loading" style="display:none;"><img alt="<?php echo $lang["Loading"];?>" src="lib/immedia/img/ajax-loader.gif" /> <?php echo $lang["Loading"];?></div>
<div class="preview" style="display:none;" id="image_message_preview">
<!-- <div>Image preview :</div>
<div id='small_message_msg'></div>
<img src='' />
<div class='btnoptions'>
<a onclick='javascript:deleteMessageImage();' href='javascript:;' class='button' title="Delete photo">
<span class='ui-icon ui-icon-closethick smsg'></span>Delete
</a>
</div>-->
</div>
Here is the javascript to automatically upload the picture
这是自动上传图片的javascript
$(document).ready(function (){
$("#image-message").on('change', function () {
$('#editor-photoarea').show();
ajaxFileUploadMessagePicture();
});
});
function uploadMessagePicture(){
//trigger the browse click
if($('#image_message_file').val() == ''){
//let the person upload a file only if none are there
$('#image-message').trigger('click');
}
}
function ajaxFileUploadMessagePicture(){
$("#msg_error_no_image_message").hide();
var imageName = $("#image-message").val();
if(imageName != ''){
$("#image_message_loading").show();
$('#sendBtn').attr('disabled', 'disabled');
$.ajaxFileUpload
(
{
url:siteRegionDir+'lib/immedia/uploadMessagePicture.php',
secureuri:false,
fileElementId:'image-message',
dataType: 'json',
success: function (data, status)
{
updateMessagePicture(data);
},
error: function (data, status, e)
{
alert(e);
}
}
)
}else{
$("#msg_error_no_image_message").show();
}
return false;
}
Here is the Javascript to delete the picture and clear the fields
这是删除图片和清除字段的Javascript
function deleteMessageImage(){
//delete the image
var file = $("#image_message_file").val();
if(file != '') {
$.post(siteRegionDir+'lib/immedia/deleteMessagePicture.php',{filename:file}, function(data) {
clearPictureAttachment();
$('#editor-photoarea').hide();//make sure it is hidden
},"html"
);
}else{
clearPictureAttachment();
$('#editor-photoarea').hide();//make sure it is hidden
}
}
function clearPictureAttachment(){
//var control = $("#image-message");
$("#image-message").attr('value', '');
//control.replaceWith( control = control.clone( true ) );//so it resets it all, truw = keep the bound events
$("#image_message_file").attr('value', '');
$("#image_message_loading").hide();
$("#image_message_upload").show();
$("#image_message_preview").hide();
}
Any help would be great! Thanks!
任何帮助都会很棒!谢谢!
采纳答案by ether
Thanks to codingrhythm for leading me on the right track.
What I did was to actually just add the on("change") call again on the field.
So I only altered the clearPictureAttachment() function (called when deleting a picture) to this:
感谢codingrhythm 带领我走上正轨。
我所做的实际上只是在场上再次添加 on("change") 调用。
所以我只将 clearPictureAttachment() 函数(删除图片时调用)更改为:
function clearPictureAttachment(){
$("#image-message").attr('value', '');
$("#image_message_file").attr('value', '');
$("#image_message_loading").hide();
$("#image_message_upload").show();
$("#image_message_preview").hide();
//reenable the onchange to upload a picture
$("#image-message").on('change', function () {
$('#editor-photoarea').show();
ajaxFileUploadMessagePicture();
});
}
Thanks again!
再次感谢!
回答by Sych
My guess is that you test your functionality with the same picture file over and over again.
我的猜测是您使用相同的图片文件一遍又一遍地测试您的功能。
If you select the same file, the onChange event of input[type=file]
will not fire.
如果选择相同的文件,input[type=file]
则不会触发onChange 事件。
Different file with the same name would not fire the event as well. Select a different image file - it will happen.
具有相同名称的不同文件也不会触发该事件。选择一个不同的图像文件 - 它会发生。
To avoid this you can reset the form to ensure that choosing a file will be performed on a clean file
control
为避免这种情况,您可以重置表单以确保选择文件将在干净的file
控件上执行
回答by I am L
If you're using React or just javascript in general you can what you can also do is "reset" the value of the event target.
如果您使用 React 或一般只使用 javascript,您还可以做的是“重置”事件目标的值。
So If you have something like a component that can upload and "remove" an image:
因此,如果您有一个可以上传和“删除”图像的组件:
<input type="file" onChange={onChange} />
your onChange
can be:
你onChange
可以:
onChange(event) {
const files = event.target.files;
// your logic here on what to do with files (maybe fetch the preview or something)
// this line right below will reset the
// input field so if you removed it you can re-add the same file
event.target.value = ''
}
回答by MKP
Synchis partially right about onchange event that it will not fire for same file..More precisely onchange in case of input type file(scenario mentioned by ether) considers file location for event triggering.
Synch关于 onchange 事件部分正确,它不会为同一个文件触发..更准确地说,在输入类型文件(ether提到的场景)的情况下 onchange考虑事件触发的文件位置。
Try this out after selecting any file
In jQuery
$("#image_message_upload [type='file']")[0].value
You will get something like "C:\fakepath\country-and-mobile-redirect-for-wordpress-dwpsxm-clipar.jpg" as output (that is the location of file selected)
选择任何文件后试试这个
在 jQuery 中
$("#image_message_upload [type='file']")[0].value
您将得到类似“ C:\fakepath\country-and-mobile-redirect-for-wordpress-dwpsxm-clipar.jpg”的输出(即所选文件的位置)
That means either you change the file name or its location, which is not right. So, more logically what we can do while deleting the file is setting input value attribute to empty("")
这意味着您更改了文件名或其位置,这是不对的。因此,从逻辑上讲,我们在删除文件时可以做的是将输入值属性设置为空(“”)
$("#image_message_upload [type='file']")[0].value=""
$("#image_message_upload [type='file']")[0].value=""
So adding this line (inside clearPictureAttachment(), as per this question) will reset the file input type and you can select the same image file with no issues.
因此,添加这一行(在 clearPictureAttachment() 内,根据此问题)将重置文件输入类型,您可以毫无问题地选择相同的图像文件。
Cheers :)
干杯:)
回答by codingrhythm
@Sync gave me the idea to solve this issue.
@Sync 给了我解决这个问题的想法。
Here is the working code, what you need to do is to clone the file input.
这是工作代码,您需要做的是克隆文件输入。
var control = $('input[type=file]');
control.replaceWith( control = control.clone( true ) );
and the event will still be fired on second time.
并且该事件仍将在第二次触发。
回答by Imran Panjwani
In angular
在角
HTML
HTML
<input #photoInput type="file" />
TS
TS
export class SomeComponent {
@ViewChild('photoInput') photoInput;
clearPictureAttachment() {
this.photoInput.nativeElement.value = '';
}
}
回答by Julian Mann
After you have done what you want to do with the file, you can reset the FileList.
完成您想要对文件执行的操作后,您可以重置 FileList。
In my React app I have this:
在我的 React 应用程序中,我有这个:
const handleLoad = evt => {
if (evt.target.files && evt.target.files[0]) {
dispatch(loadFile(evt.target.files[0].path));
}
// Reset the FileList, as otherwise the second and subsequent times
// we browse, nothing will happen, because nothing changed.
evt.target.files = new FileList();
};