背景:

制作一个类似百度输入法的智能提示框,

其中当关键词输入进来时,会有智能提示展开,实际需求是当点击智能提示框的汉字时,输入框中自动补全并关闭智能提示,

当点击其他区域时,智能提示框自动隐藏,如下所示:

分析:点击用onclick事件触发获取的值,然后点击外框用失去焦点的方式解决

但实际出现效果是:

如果添加了失去焦点的方法,点击提示文本的时候,文字也会因为输入框失去焦点而被隐藏,以至于文字无法被选中上去:

问题出现时用方法如下:

//oA是智能提示框的列表中的单个文字
oA.onclick = function(){ populateModel(this) };
// 点击提示文本,获取文本并填充到输入款中(wd是输入框)
function populateModel(cell) {
wd.value = cell.firstChild.nodeValue; clearModels();//清除自动完成行
}
//填充后清除提示
function clearModels() {
while (oUl.childNodes.length > 0) {
oUl.removeChild(oUl.firstChild);
}
oLi.style.border = "none";
}
// 失去焦点隐藏 其中输入框中有属性:onblur="upperCase()",其中oUI 是智能提示的区域
function upperCase() {
oUl.style.display = 'none';
}

解决方案: 这里不得不先讲下鼠标点击事件

鼠标事件

属性 描述 DOM
onclick 当用户点击某个对象时调用的事件句柄。 2
oncontextmenu 在用户点击鼠标右键打开上下文菜单时触发  
ondblclick 当用户双击某个对象时调用的事件句柄。 2
onmousedown 鼠标按钮被按下。 2
onmouseenter 当鼠标指针移动到元素上时触发。 2
onmouseleave 当鼠标指针移出元素时触发 2
onmousemove 鼠标被移动。 2
onmouseover 鼠标移到某元素之上。 2
onmouseout 鼠标从某元素移开。 2
onmouseup 鼠标按键被松开。

鼠标点击点击过程是先按下鼠标(mousedown)然后弹起来(mouseup),这一过程才触发了click事件,当click触发之前,也就是mouseup时,blur已经先触发失去焦点,

因此,当你点击提示框文字时,并没有触发到click事件而是因为失去了焦点而提示框提前被隐藏掉了;

所以综上分析,解决方法有两种

1 将文字被选中这一事件用mousedown来监听,当鼠标按下时,就将文字先选中,然后弹起来时再自动触发onblur事件隐藏提示框中内容:

代码如下:

 oA.onmousedown = function(){ populateModel(this) };//修改了onclick改为onmousedown,其他均不变;

2另一种方式就是,不用失去焦点的方式来隐藏DOM,而是用鼠标移出提示框区域时,触发mouseseleave事件来隐藏DOM

代码如下:

oA.onclick = function(){ populateModel(this) };//仍然使用onclick事件触发文字获取
oUl.onmouseleave = function(){ oUl.style.display = 'none'; }// 当鼠标移除提示框之外后,自动隐藏

完整的百度智能输入法提示的JS代码:


<body>
<input type="text" id="wd" name="username" onblur="upperCase()" autocomplete="off" >
<ul id="list"></ul>
</body>

<script>
var wd = document.getElementById('wd');
var oUl = document.getElementById('list'); wd.oninput = debounce(getUserAction, 100, false);
function debounce(func, wait, immediate) {
var timer = null;
var result;
var debounced = function () {
var _this = this;
var argu = arguments;
clearTimeout(timer);
if (immediate) {
if (!timer) func.apply(_this, argu);
timer = setTimeout(function () {
timer = null;
}, wait)
} else {
timer = setTimeout(function () {
func.apply(_this, argu);
}, wait)
}
return result;
}
debounced.cancel = function () {
clearTimeout(timer);
timer = null;
}
return debounced;
}
function getUserAction() {
if (wd.value) {
var oScript = document.createElement('script');
oScript.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' + wd.value + '&cb=doJson';
document.body.appendChild(oScript);
document.body.removeChild(oScript);
} else {
oUl.style.display = 'none';
}
}
function doJson(data) {
var dataList = data.s;
oUl.innerHTML = '';
if (dataList.length == 0) {
oUl.style.display = 'none';
} else {
dataList.forEach(function (item, index) {
var oLi = document.createElement('li');
var oA = document.createElement('a');
oA.onmousedown = function(){ populateModel(this) };//单击oA是的方法为populateModel
// oA.onclick = function(){ populateModel(this) };//单击oA是的方法为populateModel
// oUl.onmouseleave = function(){ oUl.style.display = 'none'; }
oA.innerText = item;
oLi.appendChild(oA);
oUl.appendChild(oLi);
oUl.style.display = 'block';
})
} }
function populateModel(cell) {
wd.value = cell.firstChild.nodeValue; clearModels();//清除自动完成行
}
function clearModels() {
while (oUl.childNodes.length > 0) {
oUl.removeChild(oUl.firstChild);
}
oLi.style.border = "none";
}
// 失去焦点隐藏
function upperCase() {
oUl.style.display = 'none'; } </script>

  

解决input中智能提示框onblur与onclick冲突的问题的更多相关文章

  1. xcode6 beta 中智能提示(自动完成)功能有时不显示的问题

    xcode6 beta 中智能提示(自动完成)功能有时不显示的问题      周银辉 xcode6 beta 中智能提示(自动完成)功能有时不显示,这让人很郁闷啊,网上老外的视频中看人家用的好好的. ...

  2. winform下的智能提示框

    winform下的智能提示框 最近在搞winform的程序,接触到有些可能以后还会用到的功能,所以写到博客园里去,第一可以加深自己的印象,第二可以在以后再遇到同样问题的时候忘记了可以马上回来看看,第三 ...

  3. 归纳一下input中span提示以及input中onchange事件

    一.当input中不含有onclick事件的时候 定义一个class为tip1的span: <td><input  type=text name='POSTNAME' nameVal ...

  4. 智能提示框---bai

    input.jsp <%@ page language="java" import="java.util.*" pageEncoding="UT ...

  5. Win7系统下VS2008安装SP1补丁解决JQuery无智能提示的问题

    jQuery在vs2008中的智能提示 1  安装VS2008SP1补丁 要确保您的vs2008已经打了sp1补丁,在vs2008的帮助里的关于,要是安装了sp1,会出现“版本 3.5 sp1”,没安 ...

  6. 在echarts中自定义提示框内容

    1.期望效果 以柱状图为例,在鼠标滑过每个数据标签时,为了更友好地显示数据内容,需要对显示的数据内容作格式化处理,添加自定义内容. 如下图,鼠标滑过每个数据项时, 第1张是默认提示框: 第2张是处理成 ...

  7. 活动中使用提示框(Toast)

    任务名称:活动中使用Toast 任务现象:点击button时,会弹出提示框:You Click Button 步骤 1.创建一个项目,新建活动和加载布局.参考: http://8c925c9a.wiz ...

  8. 解决VS不能智能提示

    前一段时间在电脑上装了VS2013,导致VS2010上不能正常进行单元测试,折腾了一番,把VS2013又给卸载了,结果发现VS2010的智能提示没有了,没有就没有吧,懒的去管,就一直用 Ctrl + ...

  9. echarts中tooltip提示框位置控制

    关键代码: position: function(point, params, dom, rect, size) { //其中point为当前鼠标的位置,size中有两个属性:viewSize和con ...

随机推荐

  1. POJ 2546

    #include<iostream> #include<numeric> #include<iomanip> #include<algorithm> # ...

  2. 线程中消费者生产者的实例代码(使用Lock类)

    http://www.cnblogs.com/DreamDrive/p/6192685.html 这个是用synchronized关键字实现的. Lock可以替换synchronized. 上面用来做 ...

  3. Centos 7 安装 Redis 3.2

    环境: Centos 7 GCC            #未安装,使用yum install gcc安装 1.下载redis 官方下载网站:https://redis.io/download.请在页面 ...

  4. vue.js过渡效果之--javascript钩子

    写在前面 姊妹篇  vue.js之过渡效果-css.今天一篇博文阅读量破300,心里还是有点小激动的.没错,我就是这么容易满足(害羞).这个数据可能连大牛一篇文章阅读量的零头都没有,但这却是我个人的一 ...

  5. 数据库设计 Step by Step (2)——数据库生命周期

    引言:数据库设计 Step by Step (1)得到这么多朋友的关注着实出乎了我的意外.这也坚定了我把这一系列的博文写好的决心.近来工作上的事务比较繁重,加之我期望这个系列的文章能尽可能的系统.完整 ...

  6. docker(三)docker镜像和镜像发布方法

    一.从公网docker hub 拉取image ~ # 搜索docker search centos~ » docker pull centos admin@steven- Using default ...

  7. Mysql字符串转换为整型

    使用Convert(字段名, 类型)方法 SELECT CONVERT(filedName, UNSIGNED INTEGER) ;

  8. 软件架构设计学习总结(4):大数据架构hadoop

    摘要:Admaster数据挖掘总监 随着互联网.移动互联网和物联网的发展,谁也无法否认,我们已经切实地迎来了一个海量数据的时代,数据调查公司IDC预计2011年的数据总量将达到1.8万亿GB,对这些海 ...

  9. FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时

    由于产品需要对视频做一系列的解析操作,利用FFmpeg命令来完成视频的音频提取.第一帧提取作为封面图片.音频重采样.字幕压缩等功能: 前一篇文章已经记录了FFmpeg在JAVA中的使用-音频提取&am ...

  10. 开源方案搭建可离线的精美矢量切片地图服务-5.Mapbox离线项目实现

    项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...