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查看html源文件
Nov 08 Javascript
在浏览器中获取当前执行的脚本文件名的代码
Jul 19 Javascript
JS刷新框架外页面七种实现代码
Feb 18 Javascript
jQuery和AngularJS的区别浅析
Jan 29 Javascript
轻松实现js图片预览功能
Jan 18 Javascript
js中删除数组中的某一元素实例(无下标时)
Feb 28 Javascript
给vue项目添加ESLint的详细步骤
Sep 29 Javascript
浅谈Angular 观察者模式理解
Nov 01 Javascript
three.js搭建室内场景教程
Dec 30 Javascript
关于vue的npm run dev和npm run build的区别介绍
Jan 14 Javascript
浅谈VUE中演示v-for为什么要加key
Jan 16 Javascript
如何优化vue打包文件过大
Apr 13 Vue.js
简单实现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 mail 通过Windows的SMTP发送邮件失败的解决方案
2009/05/27 PHP
php的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
PHP Web木马扫描器代码分享
2015/09/06 PHP
ThinkPHP5框架实现简单的批量查询功能示例
2018/06/07 PHP
PHP下载文件函数与用法示例
2019/09/27 PHP
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
百度留言本js 大家可以参考下
2009/10/13 Javascript
基于jquery的inputlimiter 实现字数限制功能
2010/05/30 Javascript
jQuery之选择组件的深入解析
2013/06/19 Javascript
jquery验证手机号码、邮箱格式是否正确示例代码
2013/07/28 Javascript
浅析JavaScript中的同名标识符优先级
2013/12/06 Javascript
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
jquery实现列表上下移动功能
2016/02/25 Javascript
基于jQuery.validate及Bootstrap的tooltip开发气泡样式的表单校验组件思路详解
2016/07/18 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
2017/02/21 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
2017/09/02 Javascript
基于 Vue 实现一个酷炫的 menu插件
2017/11/14 Javascript
js数据类型检测总结
2018/08/05 Javascript
JS编写兼容IE6,7,8浏览器无缝自动轮播
2018/10/12 Javascript
Vue中CSS动画原理的实现
2019/02/13 Javascript
Vue-input框checkbox强制刷新问题
2019/04/18 Javascript
将Python代码打包为jar软件的简单方法
2015/08/04 Python
利用python模拟sql语句对员工表格进行增删改查
2017/07/05 Python
Python unittest模块用法实例分析
2018/05/25 Python
python实现下载pop3邮件保存到本地
2018/06/19 Python
PyCharm中代码字体大小调整方法
2019/07/29 Python
使用Python给头像加上圣诞帽或圣诞老人小图标附源码
2019/12/25 Python
pytorch 实现L2和L1正则化regularization的操作
2021/03/03 Python
RealTek面试题
2016/06/28 面试题
酒店员工培训方案
2014/06/02 职场文书
党旗在我心中演讲稿
2014/09/15 职场文书
刑事代理授权委托书
2014/09/17 职场文书
党风廉正建设个人工作总结
2015/03/06 职场文书
Vue实现跑马灯样式文字横向滚动
2021/11/23 Vue.js