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 相关文章推荐
asp 取文本框名称代码
Dec 02 Javascript
jQuery验证Checkbox是否选中的代码 推荐
Sep 04 Javascript
Ext GridPanel加载完数据后进行操作示例代码
Jun 17 Javascript
JavaScript获取指定元素位置的方法
Apr 08 Javascript
浅谈js的url解析函数封装
Jun 28 Javascript
JavaScript中误用/g导致的正则test()无法正确重复执行的解决方案
Jul 27 Javascript
JavaScript浏览器对象模型BOM(BrowserObjectModel)实例详解
Nov 29 Javascript
微信小程序图片选择区域裁剪实现方法
Dec 02 Javascript
10个经典的网页鼠标特效代码
Jan 09 Javascript
详解webpack打包第三方类库的正确姿势
Oct 20 Javascript
微信小程序左滑删除实现代码实例
Sep 16 Javascript
如何在postman中添加cookie信息步骤解析
Jun 30 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
js和php邮箱地址验证的实现方法
2014/01/09 PHP
浅谈Laravel核心解读之Console内核
2018/12/02 PHP
定义select的边框颜色
2008/04/28 Javascript
Confirmer JQuery确认对话框组件
2010/06/09 Javascript
让人印象深刻的10个jQuery手风琴效果应用
2012/05/08 Javascript
javascript标签在页面中的位置探讨
2013/04/11 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
jQuery实现带有洗牌效果的动画分页实例
2015/08/31 Javascript
jQuery Validate初步体验(二)
2015/12/12 Javascript
js获取本机操作系统类型的两种方法
2015/12/19 Javascript
Markdown与Bootstrap相结合实现图片自适应属性
2016/05/04 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐)
2016/06/23 Javascript
基于jQuery实现多标签页切换的效果(web前端开发)
2016/07/24 Javascript
Easyui Tree获取当前选择节点的所有顶级父节点
2017/02/14 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
JavaScript实现一个简易的计算器实例代码
2018/05/10 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
2018/08/16 Javascript
解决Angular2 router.navigate刷新页面的问题
2018/08/31 Javascript
JavaScript实现shuffle数组洗牌操作示例
2019/01/03 Javascript
VuePress 快速踩坑小结
2019/02/14 Javascript
利用Promise自定义一个GET请求的函数示例代码
2019/03/20 Javascript
微信小程序版本自动更新的方法
2019/06/14 Javascript
通过js示例讲解时间复杂度与空间复杂度
2019/08/06 Javascript
jQuery实现视频展示效果
2020/05/30 jQuery
python脚本实现分析dns日志并对受访域名排行
2014/09/18 Python
python安装读取grib库总结(推荐)
2020/06/24 Python
django rest framework 自定义返回方式
2020/07/12 Python
开办饭店创业计划书
2013/12/28 职场文书
《鲁班和橹板》教学反思
2014/04/27 职场文书
新郎新娘致辞
2015/07/31 职场文书
公司员工培训管理制度
2015/08/04 职场文书
《日月潭》教学反思
2016/02/20 职场文书
职场:企业印章管理制度(模板)
2019/10/18 职场文书
《正面管教》读后有感:和善而坚定的旅程
2019/12/19 职场文书
jquery插件实现图片悬浮
2021/04/16 jQuery
VUE解决跨域问题Access to XMLHttpRequest at
2022/05/06 Vue.js