3

前言

上周写需求遇到了一点小坑涉及到一些小细节,今天赶上没啥事总结一下分享出来。

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

玩弄心里的鬼
1.2k 声望1.1k 粉丝

« 上一篇
fis3学习