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 相关文章推荐
Add Formatted Text to a Word Document
Jun 15 Javascript
用JS剩余字数计算的代码
Jul 03 Javascript
js判断客户端是iOS还是Android等移动终端的方法
Dec 11 Javascript
取消选中单选框radio的三种方式示例介绍
Dec 23 Javascript
JavaScript中的Math.E属性使用详解
Jun 12 Javascript
jquery根据td给相同tr下其他td赋值的实现方法
Oct 05 Javascript
Bootstrap CSS布局之列表
Dec 15 Javascript
Vue filters过滤器的使用方法
Jul 14 Javascript
以BootStrap Tab为例写一个前端组件
Jul 25 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
Aug 29 jQuery
通过一次报错详细谈谈Point事件
May 17 Javascript
学前端,css与javascript重难点浅析
Jun 11 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中最简单的字符串匹配算法
2014/12/16 PHP
PHP中快速生成随机密码的几种方式
2017/04/17 PHP
在线编辑器中换行与内容自动提取
2009/04/24 Javascript
jQuery 扩展对input的一些操作方法
2009/10/30 Javascript
IE与FireFox中的childNodes区别
2011/10/20 Javascript
jQuery结合PHP+MySQL实现二级联动下拉列表[实例]
2011/11/15 Javascript
jquery ajax方式直接提交整个表单核心代码
2013/08/15 Javascript
jquery实现类似淘宝星星评分功能有截图
2014/09/15 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
jQuery插件制作之全局函数用法实例
2015/06/01 Javascript
JS实现仿QQ面板的手风琴效果折叠菜单代码
2015/09/11 Javascript
JavaScript必知必会(十) call apply bind的用法说明
2016/06/08 Javascript
Javascript中的对象和原型(二)
2016/08/12 Javascript
使用JQuery选择HTML遍历函数的方法
2016/09/17 Javascript
Bootstrap响应式侧边栏改进版
2016/09/17 Javascript
Bootstrap基本组件学习笔记之列表组(11)
2016/12/07 Javascript
javascript 封装Date日期类实例详解
2017/05/28 Javascript
Phaser.js实现简单的跑酷游戏附源码下载
2018/10/26 Javascript
VUE2.0+ElementUI2.0表格el-table循环动态列渲染的写法详解
2018/11/30 Javascript
[02:22:36]《加油!DOTA》总决赛
2014/09/19 DOTA
[40:17]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第一场
2018/04/06 DOTA
[01:07:41]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
利用Python中的输入和输出功能进行读取和写入的教程
2015/04/14 Python
python远程连接MySQL数据库
2019/04/19 Python
django Admin文档生成器使用详解
2019/07/22 Python
Flask框架路由和视图用法实例分析
2019/11/07 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
Python切割图片成九宫格的示例代码
2020/03/10 Python
Python数据模型与Python对象模型的相关总结
2021/01/26 Python
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
阿联酋手表和配饰购物网站:Rivolishop
2019/11/25 全球购物
马来西亚奢侈品牌购物商城:Valiram 247
2020/09/29 全球购物
DJI全球:DJI Global
2021/03/15 全球购物
成人毕业生自我鉴定
2013/10/18 职场文书
表扬稿表扬信的格式及范文
2019/06/24 职场文书
经典法律座右铭(50句)
2019/08/15 职场文书