【问题标题】:Files input change event fires only once文件输入更改事件仅触发一次
【发布时间】:2011-11-03 00:35:06
【问题描述】:

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

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

【问题讨论】:

标签: javascript html dom-events


【解决方案1】:

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

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

jsfiddle test

【讨论】:

  • 如何在不使用jquery的情况下实现相同的行为?
  • e.target.value = ''
  • 非常感谢!!拯救了我的一天!
  • 你应该放一个空字符串 ("") 而不是 null
【解决方案2】:

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

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

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

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


老实说,我不知道这是否是一个合法的浏览器错误。 innerHTML“覆盖”现有的输入元素是有道理的,但浏览器足够聪明,不会重置输入的值,所以你会认为听众也会留下来……所以……嗯,这很混乱

【讨论】:

  • 无论这是否是一个合法的浏览器错误,感谢您找到我的问题所在。
【解决方案3】:

我不知道为什么,但这个老问题的答案都不是那么简单。这是今天轻松完成此操作的方法...

使用 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 = '';
};

在您将值更改为下次单击文件输入时选择的文件以外的其他内容后,onchange 事件将触发。

【讨论】:

  • 为了清楚起见... e.target.value = '' 或 e.target.value = null 等...
  • 我在 Chrome 66 上也发生了同样的事情
【解决方案4】:

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

 buttonRef.current.value = null;

【讨论】:

  • 不到一个小时前你刚刚回答这个问题的时间是什么时候
  • 很高兴能帮上忙
【解决方案5】:

使用 oninput 事件代替 onchange

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

【讨论】:

    【解决方案6】:

    以上方法都不适合我,实际上每次更改时我都必须创建一个新的“虚拟”文件输入字段 - 允许我再次捕获更改事件。

    我的过程是:

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

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        好的,根据@Flambino,输入正在重新渲染。无论出于何种原因,这对我来说都无关紧要。 $.on('change', callback) 功能丢失。

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

        好吧,delegate 是完全一样的,它只是告诉 jquery 是否有一个元素呈现在屏幕上并带有特定的句柄,并为其附加一个功能。

        所以即使元素被重新渲染,它仍然会继续工作。

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

        您可能认为这是一个丢弃功能并说出有什么区别,但这为我节省了很多项目时间。

        【讨论】:

          【解决方案9】:

          通过在每个新文件的回调结束时重新分配 .change 函数,我得到了 .change 回调:

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

          【讨论】:

            【解决方案10】:

            就我而言,我使用 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){
            
                         }
                    });
              });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-08-29
              • 1970-01-01
              • 2017-05-25
              • 1970-01-01
              • 2012-10-22
              • 2023-04-04
              • 2019-12-28
              • 2018-07-17
              相关资源
              最近更新 更多