soarli

解决blur事件与click事件的冲突
前言近日在毕设中引入了搜索框,巧妙设计前端样式后遇到了在点击搜索按钮时搜索框失去焦点事件与点击搜索按钮事件冲突的现...
扫描右侧二维码阅读全文
12
2022/03

解决blur事件与click事件的冲突

前言

近日在毕设中引入了搜索框,巧妙设计前端样式后遇到了在点击搜索按钮时搜索框失去焦点事件与点击搜索按钮事件冲突的现象,并且浏览器会优先执行blur事件从而导致click事件无法执行。

image-20220313041229010

知识

下面是关于二者的介绍:

blur事件:当元素失去焦点时触发blur事件;早前,blur 事件仅发生于表单元素上。在新浏览器中,该事件可用于任何元素,blur和focus事件不会冒泡,其他表单事件都可以。

click事件:当点击元素时触发click事件;所有元素都有此事件,会产生冒泡。

至于为什么会出现上述问题:

Javascript为单线程,同一时间只能执行处理一个事件,所以当blur执行时,会导致其后续click事件并不会执行。

解决

方法一:

click事件比blur事件先触发,可以给blur事件加定时器延迟触发:

/*删除图标的点击事件*/
 $(".delete-icon").on("click",function () {
    $(this).prev("input").val("").focus();
 });
 /*输入框失去焦点的blur事件*/
 $("input[name='username'],input[name='password']").on("blur",function () {
    var $this = $(this);
    setTimeout(function(){
       $this.parent().removeClass("active");
       $this.next(".delete-icon").hide();
   },250)
});

缺点:设置多久的延时是一个难以两全的问题,时间太短不能保证click事件的100%触发,时间太长则会造成卡顿的感觉,影响用户体验

方法二:

click事件改为mousedown事件,mousedown事件会优先于blur事件执行

/*删除图标的点击事件*/
$(".delete-icon").on("mousedown",function () {
    $(this).prev("input").val("").focus();
});
/*输入框失去焦点的blur事件*/
$("input[name='username'],input[name='password']").on("blur",function () {
    var $this = $(this);
    $this.parent().removeClass("active");
    $this.next(".delete-icon").hide();
});

缺点:鼠标按下便触发了事件,不收起、长按也会触发,可能在特殊场景下造成用户体验不好(足够满足我的需求了)

方法三:

给图标再添加一个mousedown事件,在其中执行event.preventDefault()阻止浏览器默认事件,这样点击按钮时输入框就不会失去焦点了

/*阻止浏览器默认事件*/
$(".delete-icon").on("mousedown",function(e) {
    e.preventDefault();
})
/*删除图标的点击事件*/
$(".delete-icon").on("click",function () {
    $(this).prev("input").val("").focus();
});
/*输入框失去焦点的blur事件*/
$("input[name='username'],input[name='password']").on("blur",function () {
    var $this = $(this);
    $this.parent().removeClass("active");
    $this.next(".delete-icon").hide();
});

方法四:

动态绑定blur事件,当鼠标进入input框父级元素时,移除input绑定事件blur,当鼠标移出输入框父级元素时,给input绑定blur事件

/*动态绑定blur事件*/
$(".login-con li").mouseenter(function(){
    $(this).find("input").unbind("blur");
});
$(".login-con li").mouseleave(function(event){
    $(this).find("input").bind("blur");
});
/*删除图标的点击事件*/
$(".delete-icon").on("click",function () {
    $(this).prev("input").val("").focus();
});
/*输入框失去焦点的blur事件*/
$("input[name='username'],input[name='password']").on("blur",function () {
    var $this = $(this);
    $this.parent().removeClass("active");
    $this.next(".delete-icon").hide();
});

方法三、四几乎没缺点(欢迎大佬们留言补充),可以优先考虑。

旁通

该方案亦可解决下图所示问题:

参考资料:

https://www.jianshu.com/p/791b30924c1a

https://www.w3school.com.cn/jquery/event_blur.asp

https://blog.csdn.net/ligang2585116/article/details/51764828

最后修改:2022 年 03 月 13 日 04 : 21 AM

发表评论