监听 input type=file 文件上传取消事件
在做项目的时候,需要根据是否上传图片,(前提是已经上传文件,再次上传取消时,监听取消事件)进而判断页面变化。通过查阅相关资料,发现change事件并不能监听取消,于是从另外一种角度:判断上传的文件是否有值,进而监听取消事件。
代码如下:
<input type="file" name="file" id="fileToUpload" accept="image/*" style="display:none;">
js:
var batchUpload = document.querySelector('#fileToUpload'); batchUpload.click(); batchUpload.addEventListener('change', function () { var filesList = document.querySelector('#fileToUpload').files; if(filesList.length==0){ //如果取消上传,则改文件的长度为0 console.log('取消') return; }else{ //如果有文件上传,这在这里面进行 } });
但是上面代码存在问题:
1, 如果两次选择打开相同文件,则第二次打开不会执行。
2, 若在页面对话框中选择了取消,无法监听或绑定用户取消动作。(就是第一次上传就选择取消,那么代码也不会执行)
这都是 input files 设计带来的问题,因为 input.value 值未改变, onchange 事件不会被触发。
解决问题:
解决第1个问题的思路,大部分浏览器为了安全限制 input.value 值不可修改,但是可以被置空。因此,onchange 文件打开任务完成后,将缓存 input.value 值置空,第二次打开相同的文件之前 input.value 值是空的,onchange 就会被触发。
document.querySelector(‘input’).value = “”; //有效 document.querySelector(‘input’).value = “data.xls”; //无效
解决第2个问题的思路,文件打开对话框弹出后,当前页面失去焦点,当文件选择对话框关闭(无论是确定还是取消),页面将重新获取焦点。可以绑定页面获取焦点事件,判定用户是否取消了文件选择。
需要注意的是,浏览器页面获取焦点事件早于 onchange 事件约20毫秒,需要页面绑定的事件滞后执行,使用 setTimeout 即可。
代码如下:
var FLAG = 0; //上传图片并判断条件 $('#upload').click(function () { FLAG = 1; $("#uploading").text('上传中...') }) $("#fileToUpload").change(function (e) { var fileTypes = [".jpg", ".png"]; var filePath = fileToUpload.value; console.log(filePath) if(filePath){ FLAG = 2; ...... $("#uploading").text('上传成功'); } }) // 取消上传 $(window).focus(f => { setTimeout(e => { if (FLAG == 1) { FLAG = 0; console.log('取消'); $("#uploading").text(' ') } }, 100); });
至此,两个问题完美解决。