原生的input标签无法监听取消事件, 我们通过对容器的blur事件和click事件, 以及input的change事件, 三者结合进行判断:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>选择文件的取消事件</title>
<style>
* {
font-size: large;
}
</style>
</head>
<body>
<div>
<button id="btn">选择文件</button>
</div>
<script>
addFileSelect(
btn,
/* 选择文件事件 */
(input) => {
alert(‘您选择了文件: ‘ + input.files[0].name);
},
/* 取消选择事件 */
() => {
alert(‘您取消了文件选择‘);
}
);
/**
* 为容器添加文件选择事件, 容器通常是一个按钮
*/
function addFileSelect(container, onselect, oncancel) {
// <input type="file">
let input = document.createElement(‘input‘); input.type = ‘file‘;
// states
let waiting = false; // 是否尚在等待选择文件
let clicked = false; // 按钮是否被点击
container.addEventListener(‘click‘, () => {
clicked = true; // 按钮被点击
input.click(); // 弹窗
waiting = true; // 等待用户选择文件, 此时按钮会失去焦点
});
container.addEventListener(‘blur‘, () => {
if (clicked && waiting) {
clicked = false; // 用户点击容器后, 容器会失去一次焦点, 此时处于waiting状态
} else if (waiting) { // 容器再次失去焦点, 仍旧处于waiting状态, 断言用户取消了选择
console.log(‘blur事件测试到用户取消了选择‘);
oncancel?.();
}
});
input.addEventListener(‘change‘, () => {
waiting = false; // 检测到用户选择了文件
if (input.value === ‘‘) { // 此时, 用户肯定点击了取消按钮, 否则value不会变为空串, 而且之前肯定选择过文件, 否则不会触发change事件
console.log(‘change事件感知到用户取消了选择‘);
oncancel?.();
} else {
onselect?.(input);
}
});
}
</script>
</body>
</html>
原文:https://www.cnblogs.com/develon/p/13718155.html