Files input change event fires only once

試著忘記壹切 提交于 2019-12-12 08:27:16

问题


I've made a small script using some of the HTML5 files features, which allows you to select one or more files, and each time it will write the name of the file(s). Everything works as it should, only the event to detect the value change of the files input fire only once, so how can I make it fire every change and not only on the first change?

By the way, here is what I made: http://tamir.netspot.co.il/html5/files/


回答1:


It appears that the change event listener is being removed because you're using innerHTML to update the same element (wrapper) that the input itself is inside. So the contents of the wrapper element – including the file input – is being re-rendered, and along the way, the event listener is removed (or, rather, it's connected to an element that's no longer there).

Here's a simple jsfiddle that does exactly the same as your code, except that it prints the selected file names in a different element than the element the input is in. And it works (in WebKit, anyway)

Here's further proof (I basically copied your code, and only added a line to re-register the event listener after the modification of wrapper.innerHTML)

So, the change event does fire for each change, but the input that's being observed is removed by the use of innerHTML on the input's parent element.


I honestly don't know whether this is a legitimate browser bug or not. It makes sense for innerHTML to "overwrite" the existing input element, yet the browser is smart enough to not not reset the input's value, so you'd think listeners would stick around too… so… well, it's confusing




回答2:


If you want to upload twice, clear file input value

$('input[type="file"]').val(null);

jsfiddle test




回答3:


I'm not sure why but none of the answers to this old question are all that simple. Here's the way to do this easily today...

with jquery...

$('#myfileinputfieldid')[0].onchange = function(e) {
 //do something with e.  Like write an image to a canvas or make a yummy cup of coffee
  e.target.value = '';
};

that's it after you have changed the value to something other than the file that was selected the next time the file input is clicked the onchange event will fire.




回答4:


Instead of using onchange use oninput event

 $scope.ShowIcon = function (input) {
        if (input.files && input.files[0]) {
            var reader = new FileReader();
            reader.onload = function (e) {
                $('#iAIcon')
                    .attr('src', e.target.result)
            };
            reader.readAsDataURL(input.files[0]);           
        }        
    }



回答5:


None of the above worked for me, I actually had to create a new "dummy" file input field each time it was changed - allowing me to capture the change event again.

The process for me was:

OnChange - move file input to another element - create a new file input to capture the change event again




回答6:


addEventListener wont work for IE8(Not sure about IE9 onwards). We need to use attachEvent listiner. If you need cross browser support then use this

if (!inputfile.addEventListener) {
    inputfile.attachEvent("onclick", setCheckedValues); //IE8
}else {
    inputfile.addEventListener("click", setCheckedValues, false); //Other browser
}



回答7:


ok well according to @Flambino the input is being re-rendered. For whatever reason this may be, for me its irrelevant. The $.on('change', callback) functionality is lost.

Try using .delegate function which I absolutely love! http://api.jquery.com/delegate/

Ok so delegate is exactly the same, it just tells jquery if there is an element rendered on screen with a particular handle, attach a functionality to it.

So even if the element is re-rendered, it will still keep to function.

$(document).delegate('.file_upload_btn', 'change', function(){});

You may think this is a throw away function & say whats the difference but this has saved me a lot of time on projects.




回答8:


I got the .change callback to fire on every new file by reassigning the .change function at the end of its own callback:

$('#myfileinputfieldid').change(function (event) {
    scope.processFile(event.target.files[0]);
});

scope.processFile = function(fileStruct) {
    doStuff;

    // Reassign the onchange callback.
    $('#myfileinputfieldid').change(function (event) {
        scope.processFile(event.target.files[0]);
    });
};



回答9:


In my case i use ajax to upload file. I just clear the value of input with onclick event handler.

  $('#myFile').click(function(e) {e.target.value = '';});
  $('#myFile').change(function(e) { 
           var file = e.target.value;
           var formdata = new FormData();
           formdata.append('file', file, 'somefile');
           $.ajax({
             type: 'POST',
             url: './uploadFile',
             data: formdata,
             processData: false,
             contentType: false,
             success: function(data){

             }
        });
  });


来源:https://stackoverflow.com/questions/7179627/files-input-change-event-fires-only-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!