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 相关文章推荐
使用jquery解析XML示例代码
Sep 05 Javascript
javascript实现汉字转拼音代码分享
Apr 20 Javascript
学习使用bootstrap3栅格系统
Apr 12 Javascript
jQuery+Pdo编写login登陆界面
Aug 01 Javascript
使用ReactJS实现tab页切换、菜单栏切换、手风琴切换和进度条效果
Oct 17 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
Dec 21 Javascript
JS触摸与手势事件详解
May 09 Javascript
jQuery选择器之属性筛选选择器用法详解
Sep 19 jQuery
vue实现密码显示隐藏切换功能
Feb 23 Javascript
vue .sync修饰符的使用详解
Jun 15 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
Sep 18 Javascript
vue中jsonp插件的使用方法示例
Sep 10 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
PHP5/ZendEngine2的改进
2006/10/09 PHP
使用php重新实现PHP脚本引擎内置函数
2007/03/06 PHP
PHP如何通过传引用的思想实现无限分类(代码简单)
2015/10/13 PHP
国外Lightbox v2.03.3 最新版 下载
2007/10/17 Javascript
JavaScript 页面编码与浏览器类型判断代码
2010/06/03 Javascript
Javascript计算时间差的函数分享
2011/07/04 Javascript
基于jquery的多彩百分比 动态进度条 投票效果显示效果实现代码
2011/08/28 Javascript
图片延迟加载的实现代码(模仿懒惰)
2013/03/29 Javascript
基于jquery固定于顶部的导航响应浏览器滚动条事件
2014/11/02 Javascript
JavaScript中匿名函数的用法及优缺点详解
2016/06/01 Javascript
jQuery Easyui DataGrid点击某个单元格即进入编辑状态焦点移开后保存数据
2016/08/15 Javascript
jquery实现网页定位导航
2016/08/23 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
jQuery访问浏览器本地存储cookie、localStorage和sessionStorage的基本用法
2017/10/20 jQuery
使用JS模拟锚点跳转的实例
2018/02/01 Javascript
vue2.0页面前进刷新回退不刷新的实现方法
2018/07/31 Javascript
vue下载excel的实现代码后台用post方法
2019/05/10 Javascript
vue项目实现图片上传功能
2019/12/23 Javascript
python实现rsa加密实例详解
2017/07/19 Python
Python reduce()函数的用法小结
2017/11/15 Python
TensorFlow实现RNN循环神经网络
2018/02/28 Python
Python实现京东秒杀功能代码
2019/05/16 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
Pytorch实现LSTM和GRU示例
2020/01/14 Python
python GUI库图形界面开发之PyQt5中QMainWindow, QWidget以及QDialog的区别和选择
2020/02/26 Python
keras小技巧——获取某一个网络层的输出方式
2020/05/23 Python
tensorflow从ckpt和从.pb文件读取变量的值方式
2020/05/26 Python
将pycharm配置为matlab或者spyder的用法说明
2020/06/08 Python
澳大利亚牛仔裤商店:Just Jeans
2016/10/13 全球购物
意大利专业化妆品品牌:KIKO MILANO
2017/02/01 全球购物
爱尔兰电子产品购物网站:Komplett.ie
2018/04/04 全球购物
新店开张活动方案
2014/08/24 职场文书
离婚代理词范文
2015/05/23 职场文书
建国大业观后感600字
2015/06/01 职场文书
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP
JavaScript实现队列结构过程
2021/12/06 Javascript