INPUT[type=file]的change事件不触发问题 爱被打了一巴掌 2021-07-04 22:51 925阅读 0赞 在网页上要操作文件通常会使用`INPUT[type=file]`控件,但这个控件的设计很蛋疼。它不像其它编程语言中文件选择后会触发一个事件,只是让上面的文字改变,而这个改变可能会触发`change`事件而已。对于文字没改变的选择,`change`事件则不会触发。 当`INPUT[type=file]`控件上已经选择过一次文件之后,再次点击它选择同一个文件时`change`事件就不会触发。因为第二次选择后里面的文字和第一次是一样的,没有改变。还有个更蛋疼情况是有些浏览器会自动记住控件上的文字,即使页面关闭后重新打开还是会恢复到原来的文字。这时候选择同路径的文件也不会触发`change`事件。 这些问题都是`INPUT[type=file]`控件蛋疼的设计所引起的,从一般渠道无法解决这个问题。有人建议在点击`INPUT[type=file]`控件时先清空其文字,这样在选中文件之后自然可以触发`change`事件。但一些浏览器上对`INPUT[type=file]`控件的值是只读的,要清空恐怕不容易。但从这里我们可以推广出另一种偷天换日的解决方案。既然值无法写入,为何我们不创建一个新的`INPUT[type=file]`把旧的替换掉呢?这么一来,需要解决的问题就剩下事件绑定了。这可以通过在容器上绑定事件,之后通过冒泡的方式来获取,而不把事件绑定到目标元素上的方法来解决。下面就是一个不太漂亮的解决办法(由于一些兼容代码写着麻烦,这里直接用了jQuery): 运行 <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script> <script> $(function(){ form.reset(); //清除浏览器记录的上次记录 var file; $(form).on("change","#file",function(e){ //输出选中结果 console.log(this.value); //每次选中都保存旧元素,并使用新的控件替换 $(this).clone().replaceAll(file=this); }).submit(function(){ //提交时把之前保存的旧元素替换回去 $("#file").replaceWith(file); }); }); </script> <form id="form"> <input type="file" name="file" id="file"><br/> <input type="submit" /> </form> -------------------- ## `input:file` `onchange`事件无法读取解决方法 ## 最近做项目,移动端的多文件上传,使用`input:file`读取文件 <input type='file' name='file' multiple accept='image/*' capture='camera'> 但是在移动端 设置 `multiple` 属性是不起作用的,设置此属性PC端可以多选而移动端无法多选。 我使用的解决方案是动态添加 `input:file`标签。,每添加一个标签就出发一次`click`事件读取文件。然后选择相片并且将相片显示在页面上。 一开始直接在通过JQuery绑定`change`事件,结果发现无法触发;接着用原生,也不行;最后直接将事件绑定到标签上也是不行的,全都触发不了`change`事件。 查询过后发现是`input:file`的问题 进入页面执行JS时,先将表单 `RESET`掉`form,reset();` 然后将`change`事件绑定到`form`表单上,采用事件委托。顺利解决。
还没有评论,来说两句吧...