文件输入更改事件仅触发一次

时间:2011-08-24 17:22:21

标签: javascript html5 javascript-events

我使用了一些HTML5文件功能制作了一个小脚本,它允许您选择一个或多个文件,并且每次都会写入文件的名称。一切都按原样运行,只有事件检测文件输入的值变化才会触发一次,那么我怎样才能使每次变化都触发,而不仅仅是第一次变化?

顺便说一句,这就是我所做的: http://tamir.netspot.co.il/html5/files/

9 个答案:

答案 0 :(得分:24)

如果要上传两次,请清除文件输入值

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

jsfiddle test

答案 1 :(得分:9)

似乎正在删除change事件侦听器,因为您正在使用innerHTML更新输入本身所在的同一元素(wrapper)。因此,wrapper元素的内容(包括文件输入)正在被重新呈现,并且在此过程中,事件侦听器被移除(或者更确切地说,它连接到不再存在的元素)。 / p>

Here's a simple jsfiddle与您的代码完全相同,不同之处在于它将选定的文件名打印在与输入所在元素不同的元素中。它可以工作(无论如何都在WebKit中)

Here's further proof(我基本上复制了你的代码,并且在修改wrapper.innerHTML后只添加了一行来重新注册事件监听器)

因此,change事件会针对每次更改触发,但是通过在输入的父元素上使用innerHTML来删除正在观察的输入。


老实说,我不知道这是否是合法的浏览器错误。 innerHTML“覆盖”现有的输入元素是有道理的,但浏览器足够聪明,不会重置输入的值,所以你认为听众也会坚持下去......所以......好吧,这让人感到困惑< / p>

答案 2 :(得分:2)

基本上,如果您的输入仍有值,则不会触发额外的事件。我正在使用 react,我必须清除下一个要触发的事件的输入值。 使用 ref,你可以做这样的事情。

 buttonRef.current.value = null;

答案 3 :(得分:1)

而不是使用onchange使用oninput事件

 $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]);           
        }        
    }

答案 4 :(得分:0)

以上都没有为我工作,每次更改时我都必须创建一个新的“虚拟”文件输入字段 - 允许我再次捕获更改事件。

我的过程是:

的OnChange - 将文件输入移动到另一个元素 - 创建新文件输入以再次捕获更改事件

答案 5 :(得分:0)

addEventListener不适用于IE8(不确定IE9以后)。我们需要使用attachEvent listiner。如果您需要跨浏览器支持,请使用此

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

答案 6 :(得分:0)

好吧,根据@Flambino,正在重新渲染输入。无论出于何种原因,这对我来说都是无关紧要的。 $ .on(&#39;更改&#39;,回调)功能已丢失。

尝试使用我非常喜欢的.delegate功能! http://api.jquery.com/delegate/

好的所以委托是完全一样的,只是告诉jquery是否有一个在特定句柄的屏幕上呈现的元素,附加一个功能。

因此,即使重新渲染元素,它仍将继续运行。

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

你可能认为这是一个扔掉的功能&amp;说什么是差异,但这为我节省了大量的时间。

答案 7 :(得分:0)

我通过在自己的回调末尾重新分配.change函数,使.change回调在每个新文件上触发:

run

答案 8 :(得分:0)

就我而言,我使用ajax上传文件。 我只是用onclick事件处理程序清除输入的值。

  $('#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){

             }
        });
  });