在做项目的时候,需要根据是否上传图片,(前提是已经上传文件,再次上传取消时,监听取消事件)进而判断页面变化。通过查阅相关资料,发现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);
});
至此,两个问题完美解决。