前言
上周写需求遇到了一点小坑涉及到一些小细节,今天赶上没啥事总结一下分享出来。
click事件与blur事件冲突问题
click事件与blur事件
blur事件: 表单事件,元素失去焦点时候触发,不会冒泡;
click事件: 当点击元素的时候触发,所有元素均有此事件,会冒泡;
注意:
除了focus和blur事件,其他的表单事件均会冒泡。
问题的提出
当点击某个元素导致前一个元素失去焦点的时候,blur事件会先于click事件触发。
document.querySelector('#ipt').addEventListener('blur', () => {
console.log('blur');
});
document.querySelector('#btn').addEventListener('click', () => {
console.log('click');
});
// blur
// click
解决方法
1. 延迟执行blur事件
document.querySelector('#ipt').addEventListener('blur', () => {
setTimeout(() => {
console.log('blur');
}, 100);
});
document.querySelector('#btn').addEventListener('click'() => {
console.log('click');
});
// blur
// click
2. 用mousedown事件代替click事件
mousedown事件:当鼠标指针移动到元素上方并按下鼠标按键时,触发mousedown事件。
mouseup事件:当在元素上松开鼠标按钮时,会发生mouseup事件。
注意:
mousedown和mouseup与click 事件不同。mousedown事件仅需要按键被按下,而不需要松开即可发生;mouseup事件仅需要松开按钮,当鼠标指针位于元素上方时,放松鼠标按钮就会触发该事件。
document.querySelector('#ipt').addEventListener('blur', () => {
console.log('blur');
});
document.querySelector('#btn').addEventListener('click', () => {
console.log('click');
});
document.querySelector('#btn').addEventListener('mousedown', () => {
console.log('mousedown');
});
document.querySelector('#btn').addEventListener('mouseup', () => {
console.log('mouseup');
});
// mousedown
// blur
// mouseup
// click
input文件上传同名文件问题
问题的提出
通常我们在用input做文件上传的时候,会为其绑定change事件,但是这时候会遇到一个问题,当我们在此上传同一个文件的时候,该文件已经缓存到浏览器中了,如果不刷新的话,change事件无法重复触发。
// HTML
<input type="file" id="file" />
// js
document.querySelector('#file').addEventListener('change', () => {
console.log('change');
// ...
})
// 第一次上传 file.xlsx
// change
// 第二次上传 file.xlsx 不会触发change事件
问题的解决
1. 手动触发form的reset方法
// HTML
<form id="form">
<input type="file" id="file" />
</form>
// js
document.querySelector('#file').addEventListener('change', () => {
console.log('change');
// ...
document.querySelector('#form').reset();
});
// 第一次上传 file.xlsx
// change
// 第二次上传 file.xlsx
// change
缺点: 不难看出这种方法我们必须为input元素包裹一个form元素,当只包含一个input元素时候这种方法就不适用了。
2. remove掉input元素
// HTML
<form id="form">
<input type="file" id="file" />
</form>
// js
let file = document.querySelector('#file');
file.addEventListener('change', () => {
console.log('change');
// ...
file.remove();
document.querySelector('#form').innerHTML = '<input type="file" id="file" />';
});
// 第一次上传 file.xlsx
// change
// 第二次上传 file.xlsx
// change
缺点:这种方法需要修改dom结构了dom结构,可能导致节点树的回流。
3. 更新change事件
// HTML
<form id="form">
<input type="file" id="file" />
</form>
// js
let file = document.querySelector('#file');
file.addEventListener('change', () => {
console.log('change');
// ...
file.remove();
file.onchange = function () {
// ...
}
});
// 第一次上传 file.xlsx
// change
// 第二次上传 file.xlsx
// change
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。