踩坑 - click事件與blur事件衝突問題 & input文件上傳同名文件問題

前言

上週寫需求遇到了一點小坑涉及到一些小細節,今天遇上沒啥事總結一下分享出來。瀏覽器

click事件與blur事件衝突問題

click事件與blur事件

  • blur事件: 表單事件,元素失去焦點時候觸發,不會冒泡;緩存

  • click事件: 當點擊元素的時候觸發,全部元素均有此事件,會冒泡;dom

注意:
除了focus和blur事件,其餘的表單事件均會冒泡。指針

問題的提出

當點擊某個元素致使前一個元素失去焦點的時候,blur事件會先於click事件觸發。code

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事件。orm

  • mouseup事件:當在元素上鬆開鼠標按鈕時,會發生mouseup事件。事件

注意:ip

mousedown和mouseup與click 事件不一樣。mousedown事件僅須要按鍵被按下,而不須要鬆開便可發生;mouseup事件僅須要鬆開按鈕,當鼠標指針位於元素上方時,放鬆鼠標按鈕就會觸發該事件。rem

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事件沒法重複觸發。input

// 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
相關文章
相關標籤/搜索