Javascript blur与click冲突解决办法


Posted in Javascript onJanuary 09, 2017

解决blur与click冲突

前言:

在开发中我们会经常遇到blur和click冲突的情况。下面叙述了开发中常遇到的“下拉框”的问题,并提供了两种解决方案。

一、blur和click事件简述

  1. blur事件:当元素失去焦点时触发blur事件;其为表单事件,blur和focus事件不会冒泡,其他表单事件都可以。
  2. click事件:当点击元素时触发click事件;所有元素都有此事件,会产生冒泡。

示例1:blur事件为表单事件

<input type="text" id="tel">
<script>
  document.addEventListener("blur", function(){
    console.log("my document blur");
  });

  var ipt = document.getElementById("tel");
  ipt.addEventListener("blur", function(){
    console.log("my input blur");
  });
</script>
// 输出结果:document为非表单元素
my input blur

示例2:click事件可冒泡

<input type="text" id="tel">
<script>
  document.addEventListener("click", function(){
    console.log("my document click");
  });

  var ipt = document.getElementById("tel");
  ipt.addEventListener("click", function(){
    console.log("my input click");
  });
</script>
// 输出结果:
my input click
my document click

示例3:点击某元素导致前一个元素失去焦点,blur事件优先于click事件

<input type="text" id="ipt">
<input type="button" id="btn" value="点我">
<script>
  var ipt = document.getElementById("ipt");
  ipt.addEventListener("blur", function(){
    console.log("my input blur");
  });

  var btn = document.getElementById("btn");
  btn.addEventListener("click", function(){
    console.log("my button click");
  });
</script>
// 输出结果:
my input blur
my button click

二、下拉框blur和click事件冲突,导致不能正常选择值

实际开发中,我们会经常遇到某一下拉列表框,点击其他元素消失列表框;点击下拉框子元素使其生效的需求。这就会面临冲突问题。

<!-- DOM结构示意 -->
<input type="text" placeholder="请选择姓氏" readonly>
<div class="search-list" data-status="hide">
  <ul>
    <li><a href="javascript:">赵</a></li>
    <li><a href="javascript:">钱</a></li>
    <li><a href="javascript:">孙</a></li>
    <li><a href="javascript:">李</a></li>
  </ul>
</div>
/** 说明:
 * 目前通过ul外层div自定义属性“data-status”控制其是否显示  
 */
(function($){
  $("input").focus(function(){
    // input框获取焦点,展示下拉框
    $(".search-list").attr("data-status", "show");
  }).blur(function(){
    // input框失去焦点,隐藏下拉框
    $(".search-list").attr("data-status", "hide");
  });
  // 选择对应选项,并赋值给input框
  $(".search-list li a").click(function(){
    console.log("执行");
    $("input").val($(this).text());
  });
})(jQuery);

执行上述代码,会出现一个问题,并不能正确获取下拉框中某值。

原因:由于JavaScript为单线程,同一时间只能执行处理一个事件。由上述示例3,可得知“blur优先于click执行”。而在本示例中,由于blur处理程序,会将对应的下拉框展示区隐藏,所以导致其后续click事件并不会执行。上述console的信息也不会被输出。

解决方案1:对blur事件进行延迟,让click先执行。

(function($){
  $("input").focus(function(){
    // input框获取焦点,展示下拉框
    $(".search-list").attr("data-status", "show");
  }).blur(function(){
    setTimeout(function(){
      // input框失去焦点,隐藏下拉框
      $(".search-list").attr("data-status", "hide");
    }, 300);
  });
  // 选择对应选项,并赋值给input框
  $(".search-list li a").click(function(){
    console.log("执行");
    $("input").val($(this).text());
  });
})(jQuery);

三、使用mousedown让其优先执行

示例4:将示例3中的click事件改为mousedown

<input type="text" id="ipt">
<input type="button" id="btn" value="点我">
<script>
  var ipt = document.getElementById("ipt");
  ipt.addEventListener("blur", function(){
    console.log("my input blur");
  });

  var btn = document.getElementById("btn");
  btn.addEventListener("mousedown", function(){
    console.log("my button mousedown");
  });
</script>
// 输出结果:
my button mousedown
my input blur

mousedown事件:当鼠标指针移动到元素上方,并按下鼠标按键时,会发生mousedown事件。

mouseup事件:当在元素上放松鼠标按钮时,会发生mouseup事件。

注意:

(1)mousedown与click 事件不同,mousedown事件仅需要按键被按下,而不需要松开即可发生。
(2)mouseup与click事件不同,mouseup事件仅需要放松按钮。当鼠标指针位于元素上方时,放松鼠标按钮就会触发该事件。

补充:mousedown、mouseup、click

<input type="button" id="btn" value="点我">
var btn = document.getElementById("btn");
btn.addEventListener("mousedown", function(){
  console.log("my button mousedown");
});
btn.addEventListener("click", function(){
  console.log("my button click");
});
btn.addEventListener("mouseup", function(){
  console.log("my button mouseup");
});
输出结果:
my button mousedown
my button mouseup
my button click

所以,其执行顺序为:

mousedown >> mouseup >> click

解决方案2:将click事件改为mousedown,让其优先于blur事件执行

(function($){
  $("input").focus(function(){
    // input框获取焦点,展示下拉框
    $(".search-list").attr("data-status", "show");
  }).blur(function(){
    // input框失去焦点,隐藏下拉框
    $(".search-list").attr("data-status", "hide");
  });
  // 选择对应选项,并赋值给input框
  $(".search-list li a").mousedown(function(){
    $("input").val($(this).text());
  });
})(jQuery);

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
JS维吉尼亚密码算法实现代码
Nov 09 Javascript
js判断两个日期是否相等的方法
Sep 10 Javascript
js关于字符长度限制的问题示例探讨
Jan 24 Javascript
jquery和js实现对div的隐藏和显示方法
Sep 26 Javascript
js获取字符串最后一位方法汇总
Nov 13 Javascript
探寻JavaScript中this指针指向
Apr 23 Javascript
微信开发 使用picker封装省市区三级联动模板
Oct 28 Javascript
JavaScript通过改变文字透明度实现的文字闪烁效果实例
Apr 27 Javascript
webpack踩坑之路图片的路径与打包
Sep 05 Javascript
jQuery length 和 size()区别总结
Apr 26 jQuery
关于Vue Router中路由守卫的应用及在全局导航守卫中检查元字段的方法
Dec 09 Javascript
详解node.js创建一个web服务器(Server)的详细步骤
Jan 15 Javascript
简单实现jQuery级联菜单
Jan 09 #Javascript
prototype与__proto__区别详细介绍
Jan 09 #Javascript
jQuery实现二维码扫描功能
Jan 09 #Javascript
详解Jquery 遍历数组之$().each方法与$.each()方法介绍
Jan 09 #Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
Jan 09 #Javascript
基于jQuery实现滚动刷新效果
Jan 09 #Javascript
用jQuery实现优酷首页轮播图
Jan 09 #Javascript
You might like
yii实现创建验证码实例解析
2014/07/31 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
php简单中奖算法(实例)
2017/08/15 PHP
如何在PHP中使用AES加密算法加密数据
2020/06/24 PHP
Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0
2008/03/22 Javascript
Ruffy javascript 学习笔记
2009/11/30 Javascript
23个超流行的jQuery相册插件整理分享
2011/04/25 Javascript
js控制鼠标事件移动及移出效果显示
2014/10/19 Javascript
javascript中的Base64、UTF8编码与解码详解
2015/03/18 Javascript
JS数字抽奖游戏实现方法
2015/05/04 Javascript
bootstrap PrintThis打印插件使用详解
2017/02/20 Javascript
JavaScript对象引用与赋值实例详解
2017/03/15 Javascript
CSS3+JavaScript实现翻页幻灯片效果
2017/06/28 Javascript
jQuery表单设置值的方法
2017/06/30 jQuery
详解vue 组件之间使用eventbus传值
2017/10/25 Javascript
vue组件数据传递、父子组件数据获取,slot,router路由功能示例
2019/03/19 Javascript
JavaScript如何把两个数组对象合并过程解析
2019/10/10 Javascript
微信小程序实现多行文字超出部分省略号显示功能
2019/10/23 Javascript
vue实现商品列表的添加删除实例讲解
2020/05/14 Javascript
Python字符串和文件操作常用函数分析
2015/04/08 Python
python实现的简单抽奖系统实例
2015/05/22 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
Python Flask基础教程示例代码
2018/02/07 Python
python3.6.3+opencv3.3.0实现动态人脸捕获
2018/05/25 Python
ActiveMQ:使用Python访问ActiveMQ的方法
2019/01/30 Python
澳大利亚足球鞋和服装购物网站:Ultra Football
2018/10/11 全球购物
最新的小工具和卓越的产品设计:Oh That Tech!
2019/08/07 全球购物
大学生村官心得体会范文
2014/01/04 职场文书
《走一步再走一步》教学反思
2014/02/15 职场文书
旅游安全协议书
2014/04/21 职场文书
情感电台广播稿
2015/08/18 职场文书
幼儿园2016年圣诞活动总结
2016/03/31 职场文书
2019求职信大礼包
2019/05/15 职场文书
高考升学宴主持词
2019/06/21 职场文书
Python Pandas数据分析之iloc和loc的用法详解
2021/11/11 Python
python语言中pandas字符串分割str.split()函数
2022/08/05 Python