踩坑 - click事件与blur事件冲突问题 & input文件上传同名文件问题

BitLogicistX
• 阅读 4035

前言

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

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
点赞
收藏
评论区
推荐文章
Karen110 Karen110
4年前
盘点JavaScript focus/blur(聚焦)实际应用
大家好,我进阶学习者。一、前言当用户点击某个元素或使用键盘上的Tab键选中时,该元素将会获得聚焦(focus)。当网页加载时,HTML特性(attribute)。autofocus也可以让一个焦点落在元素上,不仅如此,还有其它途径可以获得焦点。二、focus/blur事件当元素聚焦时,会触发focus事件,当元素失去焦点时,会触发blur事件。
菜园前端 菜园前端
2年前
JavaScript中常用事件
原文链接:鼠标事件鼠标单击事件click在文档中鼠标进行单击,就会触发事件。javascriptvari0document.addEventListener('click',function()console.log(i))鼠标双击事件dblclick
LinMeng LinMeng
4年前
v-on绑定多个方法
von绑定多个方法触发机制不同语法如下:<divvon"{click:getSome,mousemove:MouseClick}"von绑定多个方法</div一个事件绑定多个函数触发机制相同,较少<div@click"getA(),getB()"一个事件绑定多个函数</div
LinMeng LinMeng
4年前
解决ios软键盘收回时屏幕空白问题
添加事件:window.scrollTo(x,y)在input的释焦事件中添加blur事件,参数X要在窗口文档显示区左上角显示的文档的x坐标。参数y要在窗口文档显示区左上角显示的文档的y坐标。添加jQuery插件mounted(){//解决ios软键盘弹出屏幕空白$("input,select,te
Stella981 Stella981
3年前
Android开发之使用pull解析XML文件
Android已经集成进了Pull解析器,所以无需添加任何jar文件。android系统本身使用到的各种xml文件,其内部也是采用Pull解析器进行解析的。Pull解析器的运行方式与SAX解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是,Pull解析器产生的事
Stella981 Stella981
3年前
JavaScript事件
事件通常与函数配合使用,这样就可以通过发生的事件来驱动函数执行。FF:Firefox,N:Netscape,IE:InternetExplorer属性当以下情况发生时,出现此事件     FF  N   IEonabort图像加载被中断134onblur元素失去焦点1
Easter79 Easter79
3年前
Swing自定义事件
1.Swing自定义事件将一个组件的事件传递给另一个组件.使用EventListenerList来管理事件,当A组件触发事件的时候,调用方法fireActionPerformed()来触发事件,然后再B组件中actionPerformed()方法来接收事件.当在容器KeyTextComponent中按下鼠标,我们就可以在Jframe中捕获触发的事
Stella981 Stella981
3年前
JavaScript事件详解
1.事件传播机制:事件冒泡,事件捕获。2.注册事件处理程序方式:设置html标签属性为事件处理程序,文档元素的事件处理程序属性,名字由“on”后面跟着事件名组成,例如:onclick,onmouseover,用法如下1<d
Stella981 Stella981
3年前
JavaScript事件属性event.target和currentTarget 属性的区别。
event.target获取的是触发事件的标签元素event.currentTarget获取到的是发起事件的标签元素一、事件属性:event.targettarget事件委托的定义:本来该自己干的事,但是自己不干,交给别人来干例子1!(https://oscimg.oschina.n
Stella981 Stella981
3年前
JavaScript——页面相关事件
页面事件是在页面加载或改变浏览器的大小、位置,以及对页面中的滚动条进行操作时,所触发的事件处理程序。加载与卸载事件加载事件(onload)是在网页加载完毕后触发相应的事件处理程序,它可以在网页加载完成后对网页中的表格样式、字体、背景颜色等进行设置。卸载事件(unload)是在卸载网页时触发相应的事件处理程序,卸载网页是指关闭当前页或
飞码LowCode前端技术系列(二):如何便捷配置出页面 | 京东云技术团队
一、配置解法中飞码提出了至少需要满足2个大能力点以及对应16个细化点。在业务复杂的场景下数据具有流转性质,事件的触发会改变数据、同时也会触发其他事件等情况。飞码使用数据驱动事件驱动的模式解决数据流转性与事件不确定性问题。数据驱动事件驱动的模式决定了需要