下拉框click事件与搜索框blur事件的爱恨纠葛
还原车祸现场
功能类似于百度搜索,搜索框输入内容,下拉框显示候选项,点击候选项就选择候选项,然后下拉框隐藏,点击外面就直接隐藏下拉框,于是我写了以下代码
//参会单位联想
$('input[name="company_name"]').bind('input propertychange', function() {
var _this = this;
clearTimeout(this.timer);
this.timer = setTimeout(function(){
$.ajax({
url:domin+'/api/company/index',
data:{
k:_this.value
},
dataType:'jsonp',
success:function(res){
if(res.status.code==0){
if(res.data.length<=0) return false;
var str = "";
res.data.forEach(function(e,i){
str += '<dd data-value="'+e.id+'" data-type="'+e.role_code+'" class="">'+e.name+'</dd>';
})
$('#company_list').html(str);
$(_this).parent().addClass('layui-form-selected');
}else {
form.val("beforehand", {
"company-type": "",
});
}
}
})
}, 1000);
$('#company_list').on('click','dd',function(){
_this.value = this.innerHTML;
postData.company_id = $(this).data('value');
form.val("beforehand", {
"company-type": company_type[$(this).data('type')]?company_type[$(this).data('type')]:"普通",
});
$(_this).parent().removeClass('layui-form-selected');
$(this).parent().html('');
isSelect = false;
})
});
$('input[name="company_name"]').blur(function(ev){
$('input[name="company_name"]').parent().removeClass('layui-form-selected');
})
先去请求数据,然后渲染列表,然后监听候选项点击,最后blur的时候隐藏下拉框,觉得自己写的很完美,于是便兴冲冲的去测试,但是一测试我发现了大问题,在我点击列表项也就是 dd 的时候,下拉框直接隐藏了,候选项的内容也没有被填到input里面去。我便很费解,于是便去找度娘玩耍,众说纷纭,我在很多胡扯的评论中终于找到了。总结如下,看看完整的步骤
- 点击 dd ,此时先触发 mousedown
- input 的 blur 触发
- 下拉框消失
- 此时鼠标抬起并不是在下拉框上
- dd 的 click 并没有触发
解决方案
- 监听的document的mouseup而不是input的blur事件,这样先触发dd的mouseup,此时数据就已经取到,然后冒泡到document,移除下拉框(类似于百度搜索)
- 监听dd的mousedown,这也会先取值,然后input再失焦(体验不太好,用户按下就会触发,不允许纠结,比如我按下第一个的时候,突然想选择第二个)
- dd还是,input还是blur,全局定义一个isSelect变量,监听dl的mousedown 触发以后修改isSelect = true ,这样在blur时,先判断isSelect 就好了。(代码如下)
var isSelect = false;
// some code
$('#company_list').on('click','dd',function(){
_this.value = this.innerHTML;
postData.company_id = $(this).data('value');
form.val("beforehand", {
"company-type": company_type[$(this).data('type')]?company_type[$(this).data('type')]:"普通",
});
$(_this).parent().removeClass('layui-form-selected');
$(this).parent().html('');
isSelect = false; //++
})
// some code
// 以下为新增
$('#company_list').mousedown(function(){
// 下拉框mousedown时,保存下拉框为真
isSelect = true;
// 注册定时器 0毫秒以后触发,在定时器触发之前 ,input 的失焦事件触发此时isSelect为真
setTimeout(function(){
// 此时input的失焦已经触发了
isSelect = false;
$('input[name="company_name"]').focus()
},0)
})
$('input[name="company_name"]').blur(function(ev){
if(!isSelect){//++
$('input[name="company_name"]').parent().removeClass('layui-form-selected');
}//++
})
虽然 setTimeout 是0毫秒的延迟,但是他在下一次的事件队列中,所以会先执行 input 的 blur 事件,再执行 setTimeout 。
有关事件循环 EventLoop 的知识,大家可以自行百度,理解了这个,虽然不会让你写代码变厉害,但是对理解js是有很大的作用的。不过想彻底理解,需要理解宏任务 task 与微任务 Microtasks ,以及 Promise 。
下次可能会写一下关于 EventLoop 的东西。
下拉框click事件与搜索框blur事件的爱恨纠葛的更多相关文章
- ideal取消按下两次shift弹出搜索框 修改idea,webstrom,phpstrom 快捷键double shift 弹出search everywhere
因为经常需要在中英文之间切换,所以时常使用shift键,一不小心就把这个Searchwhere 对话框调出来了,很是麻烦. 因此痛定思痛, 我决定将这个按两下shift键就弹出搜索框的快捷键禁用了! ...
- 下拉选择select和复选框checkbox的状态的各种方式
复选框的状态 <input name="ck" value=" " type="checkbox" checked> 或者&l ...
- jQuery 滚动条 滚动到底部(下拉到底部) 加载数据(触发事件、处理逻辑)、分页加载数据
1.针对浏览器整个窗口滚动 主要代码: <script type="text/javascript"> ; function GetProductListPageFun ...
- Html5+Mui前端框架,开发记录(四):下拉菜单绑定数据、搜索、时间控件
1.下拉菜单绑定数据,选择后回传值 1)html: <div class="mui-input-row"> <label>xxx:</label> ...
- input输入框的的input事件和change事件以及change和blur事件的区别
input输入框的 oninput事件 ,在用户输入的时候触发,只要元素值发生变化就会触发 input输入框的 onchange事件 ,要在输入框失去焦点的时候触发事件,当鼠标在其他地方点击一下才会触 ...
- 开发手机APP过程,不同使用场景APP搜索框的样式及区别
搜索框是 app 内最常见的控件之一,可以帮助用户快速又精准找到期望的内容与功能.不同的使用场景下,根据页面中搜索的重要程度,搜索框也有着不同的样式. 下面就常州开发APP公司和大家聊聊常见的四种样式 ...
- typecho博客组插件:openSug.js百度搜索框下拉提示免费代码
Typecho候选搜索增强插件:安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让Typecho搜索更便捷! 支持百度.谷歌.雅虎.Yandex.360好搜.UC神马.酷狗.优酷.淘 ...
- z-blog博客组插件openSug.js百度搜索下拉框提示代码
z-blog安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让z-blog搜索更便捷! https://www.opensug.org/.../opensug_z-blog_v1.0 ...
- Discuz论坛搜索下拉框插件openSug
Discuz!只需安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让您的Discuz搜索更便捷! 下载:https://www.opensug.org/faq/.../opensug.d ...
随机推荐
- Spring-注入
一.Spring的基本介绍:Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建.简单来说,Spring是一个分层的JavaSE/ ...
- mysql 查询 练习题及答案
CREATE DATABASE school;USE school;/*1.创建student表格*//*id为主键 非空 唯一 */CREATE TABLE student (id INT(10) ...
- racket安装
https://www.cnblogs.com/scige/p/3379447.html
- spring 相关注解详情(一)
1.@controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层2.@service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理3.@repos ...
- Vue学习记录第二天
又来做笔记啦,今天又自暴自弃了,还好及时清醒过来了,什么时候努力都不晚,主要是要一直坚持下去,只要坚持就一定会有收获,所有成功得人背后都是付出了巨大得努力的,没有人平白无故的成功.看似光鲜亮丽的背后, ...
- numpy交换列
x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print(x) x = x[:, [1, 0, 2]] print(x) 输出 [[1 2 3] [4 ...
- 详解Java内存区域?虚拟机类加载机制?
一.Java运行时数据区域 1.程序计数器 “线程私有”的内存,是一个较小的内存空间,它可以看做当前线程所执行的字节码的行号指示器.Java虚拟机规范中唯一一个没有OutOfMemoryError情况 ...
- U盘制作系统盘的方法:
1, 使用 u 盘制作 ubuntu16.04 的方法, 安装软件后,直接使用软件将 U盘制作成系统盘就好了 [1] 下载安装工具: UltraISO 官网: http://www.ezbsyst ...
- 混合开发使用Chrome Inspect调试WebView预览手机界面和定位元素
使用Chrome Inspect调试混合应用可以帮助我们排查问题.例如定位元素,快速修改CSS样式并实时查看效果.其实微信开发也是一种混合开发模式,微信可以看做一个原生的Android App搭配了一 ...
- C语言中格式字符串
C语言中格式字符串的一般形式为: %[标志][输出最小宽度][.精度][长度]类型, 其中方括号[]中的项为可选项. 一.类型 我们用一定的字符用以表示输出数据的类型,其格式符和意义下表所示: 字符 ...