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 相关文章推荐
小议javascript 设计模式 推荐
Oct 28 Javascript
SWFObject 2.1以上版本语法介绍
Jul 10 Javascript
用XMLDOM和ADODB.Stream实现base64编码解码实现代码
Nov 28 Javascript
JS getAttribute和setAttribute(取得和设置属性)的使用介绍
Jul 10 Javascript
仿谷歌主页js动画效果实现代码
Jul 14 Javascript
js写的方法实现上传图片之后查看大图
Mar 05 Javascript
14 个折磨人的 JavaScript 面试题
Aug 08 Javascript
详解超简单的react服务器渲染(ssr)入坑指南
Feb 28 Javascript
node将geojson转shp返回给前端的实现方法
May 29 Javascript
微信小程序实现拖拽功能
Sep 26 Javascript
JavaScript原生数组函数实例汇总
Oct 14 Javascript
ant-design-vue中tree增删改的操作方法
Nov 03 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
PHP文件管理之实现网盘及压缩包的功能操作
2017/09/20 PHP
jscript之Read an Excel Spreadsheet
2007/06/13 Javascript
JavaScript实现GriwView单列全选(自写代码)
2013/05/13 Javascript
JavaScript:new 一个函数和直接调用函数的区别分析
2013/07/10 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
提取jquery的ready()方法单独使用示例
2014/03/25 Javascript
javascript父、子页面交互技巧总结
2014/08/08 Javascript
判断浏览器的内核及版本号方法汇总
2015/01/05 Javascript
jQuery中Ajax的load方法详解
2015/01/14 Javascript
分享经典的JavaScript开发技巧
2015/11/21 Javascript
Bootstrap每天必学之按钮(一)
2015/11/24 Javascript
js实现浏览器倒计时跳转页面效果
2016/08/12 Javascript
JavaScript获取URL中参数querystring的方法详解
2016/10/11 Javascript
JS定时检测任务任务完成后执行下一步的解决办法
2016/12/22 Javascript
详解angular element()方法使用
2017/04/08 Javascript
jquery网页加载进度条的实现
2017/06/01 jQuery
Echart折线图手柄触发事件示例详解
2018/12/16 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
vue3.0生命周期的示例代码
2020/09/24 Javascript
[00:12]2018DOTA2亚洲邀请赛 Sccc亮相SOLO赛,今年他又会有什么样的战绩?
2018/04/06 DOTA
netbeans7安装python插件的方法图解
2013/12/24 Python
Python学习笔记之While循环用法分析
2019/08/14 Python
基于Django统计博客文章阅读量
2019/10/29 Python
python 实现屏幕录制示例
2019/12/23 Python
Python API 操作Hadoop hdfs详解
2020/06/06 Python
Python用来做Web开发的优势有哪些
2020/08/05 Python
用HTML5实现鼠标滚轮事件放大缩小图片的功能
2015/06/25 HTML / CSS
SHEIN香港:价格实惠的女性时尚服装
2018/08/14 全球购物
生产主管岗位职责
2013/11/10 职场文书
环境科学专业个人求职的自我评价
2013/11/28 职场文书
学术会议欢迎词
2014/01/09 职场文书
高中生的自我鉴定范文
2014/01/24 职场文书
赡养老人协议书范本
2015/08/06 职场文书
2016年学习雷锋精神广播稿
2015/12/17 职场文书
如何写好闭幕词
2019/04/02 职场文书
如何用PHP websocket实现网页实时聊天
2021/05/26 PHP