背景:

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

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

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

分析:点击用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. ssh登录时在参数中加入密码的解决方案

    在使用ssh登录远程服务器的时候,在执行完ssh user@ip后,要输入登录密码,有时候登录密码记不住,这样以来Ian带来的很多的麻烦,有没有一种在ssh的参数中直接加入密码的方法呢?查看ssh的帮 ...

  2. ASP.NETCore学习记录(二) —— ASP.NET Core 中间件

    ASP.NET Core 中间件 目录: 什么是中间件 ? IApplicationBuilder 使用 IApplicationBuilder 创建中间件 Run.Map 与 Use 方法 实战中间 ...

  3. git merge 的过程及冲突处理演示

    master分支上有一个1.txt文件,进行修改后提交 $ cat 1.txt 1 11 12 $ echo 13 >> 1.txt $ git commit -a -m "mo ...

  4. PHP的语言构造器

    isset和empty看起来像是函数,我们也经常把它当作函数一样使用,但是实际上,它们是语言构造器. php中的语言构造器就相当于C中的预定义宏的意思,它属于php语言内部定义的关键词,不可以被修改, ...

  5. Django使用Signals监测model字段变化发送通知

    上一篇文章<运维效率之数据迁移自动化>中讲到了工单通知,本文将介绍工单通知实现过程中的一些小技巧.所有演示均基于Django2.0 阅读此篇文章你可以: 解锁一个python if的使用新 ...

  6. PTA (Advanced Level) 1007 Maximum Subsequence Sum

    Maximum Subsequence Sum Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous su ...

  7. Java NIO系列教程(六) Selector

    Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...

  8. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 热更新Live2D

    live2D是一个很强大的2D动画组件.我们可以使用AS3脚本对它进行热更新. live2D在Unity中的使用请看这里: 如何获取Live2D 总得来说,我们可以先去live2D官网下载它的Unit ...

  9. 并发编程之 线程协作工具 LockSupport

    前言 在前面的文章中,我们介绍了并发工具中的4个,Samephore,CyclicBarrier,CountDownLatch,Exchanger,但是我们漏了一个,非常的好用的工具,楼主在这里必须加 ...

  10. C#调用百度地图API经验分享(四)

    这一篇,记录一下我调用的地图API实现的功能.下面介绍的都是一些片段的节选,不能直接复制就运行.在实现之前肯定要加载地图,先放一个webbroser控件,然后如下: private void Form ...