让input框实现类似百度的搜索提示(基于jquery事件监听)


Posted in Javascript onJanuary 31, 2014

挺炫的一个效果,百度和谷歌好像已实现好多年了,我以为在网上能轻易找到代码来实现这个效果。真正遇到这个需求,发现还真找不到。于是自己动手写这个效果,由于我是把效果整合到我的整套框架里,所以没有进行单独的封装。

需求:
实现带提示的input框,类似百度搜索,有改动的时候去获取常用关键词,数据来源于系统数据库,支持鼠标选择或键盘选择

思路:
框架一贯思路,通过class作为监听入口,通过data作为数据传递;
通过监听input和propertychange事件实现实时的改动监听,input是主流,propertychange是ie,你懂的;
通过ajax实现post动作,把返回内容显示成类似选框的形式;
监听键盘的上键(38)、下键(40)、回车键(13),通过绑定keydown,判断event.keycode实现;
监听鼠标的mouseover和click事件,与键盘动作要完美结合;
若input内容要求与已知选项必须一致,则监听blur事件,判断是否允许换焦点;

实现代码:

//By COoL //定义全局变量用于储存提示层 
var liketips; 
//监听改动或得到焦点事件 
//禁用chrome和firefox浏览器自带的自动提示 
$('.getsearchjson').attr("autocomplete","off"); 
$('.getsearchjson').bind("propertychange input focus",function(event){ 
    $this=$(this); 
    if(event.type!='focus'){ 
        //如果有改变,则状态定为必须重新选择,因为纯人手输入会导致value无法插入 
        $this.data('ok',false); 
    } 
    //获取input框位置并计算提示层应出现的位置 
    var top=1*$this.offset().top+25; 
    var left=1*$this.offset().left; 
    var width=1*$this.width()+12; 
    //重建储存提示层并让其在适当位置显示 
    $(liketips).remove(); 
    liketips=document.createElement('div'); 
    $liketips=$(liketips); 
    //class样式这里不提供,最主要是position:absolute 
    $liketips.addClass("liketips"); 
    $liketips.css({top:top+'px',left:left+'px',width:width+'px'}); 
    //加载前先显示loading动态图 
    $liketips.append('<img src="/images/loading.gif" border="0" />'); 
    $liketips.appendTo($this.parent()); 
    $liketips.show(); 
    //定义ajax去获取json,type参数通过data-type设置,keyword则是目前已输入的值 
    //返回值以table形式展示 
    $.post('/data/search.do',{type:$this.data('type'),keyword:$this.val()},function(json){ 
        $liketips.empty(); 
        var htmlcode="<table cellspacing='0' cellpadding='2'><tbody>"; 
        for(var i=0;i<json.datas.length;i++){ 
            //这里我需要用到value和title两项,所以用data-value传递多一个参数,在回车或鼠标点击后赋值到相应的地方,以此完美地替代select 
            htmlcode+='<tr data-value="'+json.datas[i][0]+'"><td>'+json.datas[i][1]+'</td></tr>'; 
        } 
        htmlcode+="</tbody></table><span>请务必在此下拉框中选择</span>"; 
        //把loading动态图替换成内容 
        $liketips.html(htmlcode); 
    },"json"); 
}); 
//焦点消失时确保数据来自选项,隐藏提示框体 
$('.getsearchjson').blur(function(){ 
    //因为鼠标点击时blur动作结算在click之前,setTimeout是为了解决这个问题 
    $oldthis=$(this); 
    setTimeout(function(){ 
        if($oldthis.data('ok')) 
            $(liketips).fadeOut('fast'); 
        else{ 
            alert('为保证数据准确性,请务必在下拉提示中选择一项,谢谢合作'); 
            $oldthis.focus(); 
        } 
    },200); 
}); 
//监听键盘动作 
$('.getsearchjson').keydown(function(event){ 
    //console.log(event.keyCode); 
    $this=$(this); 
    if(event.keyCode==40){ 
        //按键是向下 
        $nowtr=$('tr.selectedtr'); 
        //如果已存在选中,则向下,否则,选中选单中第一个 
        if($nowtr.length>0){ 
            $nexttr=$nowtr.next('tr') 
            //如果不是最后选项,向下个tr移动,否则跳到第一个tr 
            if($nexttr.length>0){ 
                $('tr.selectedtr').removeClass(); 
                $nexttr.addClass('selectedtr'); 
            } 
            else{ 
                $('tr.selectedtr').removeClass(); 
                $nowtr.parent().find('tr:first').addClass('selectedtr'); 
            } 
        } 
        else{ 
            $('.liketips').find('tr:first').addClass('selectedtr'); 
        } 
    } 
    else if(event.keyCode==38){ 
        //按键是向上 
        $nowtr=$('tr.selectedtr'); 
        //如果已存在选中,则向下,否则,选中选单中第一个 
        if($nowtr.length>0){ 
            $prevtr=$nowtr.prev('tr') 
            //如果不是最后选项,向下个tr移动,否则跳到第一个tr 
            if($prevtr.length>0){ 
                $('tr.selectedtr').removeClass(); 
                $prevtr.addClass('selectedtr'); 
            } 
            else{ 
                $('tr.selectedtr').removeClass(); 
                $nowtr.parent().find('tr:last').addClass('selectedtr'); 
            } 
        } 
        else{ 
            $('.liketips').find('tr:last').addClass('selectedtr'); 
        } 
    } 
    else if(event.keyCode==13){ 
        //按键是回车,则确定返回并隐藏选框 
        $nowtr=$('tr.selectedtr'); 
        if($nowtr.length==1){ 
            //设置value值到input框通过参数data-valueto配置的value值存储项中去,一般是hidden项 
            $valuefield=$('input[name='+$this.data('valueto')+']'); 
            $valuefield.val($nowtr.data('value')); 
            $this.val($nowtr.text()); 
            //设置状态是从选项中选择,允许blur 
            $this.data('ok',true); 
        } 
        $(liketips).fadeOut('fast'); 
        return false; 
    } 
    //console.log(event.keyCode); 
    return true; 
}); 
//监听鼠标动作,mouseover改变选中项 
$(document).delegate('.liketips td','mouseover',function(){ 
    $nowtr=$(this).parent(); 
    $nowtr.siblings('tr').removeClass(); 
    $nowtr.addClass('selectedtr'); 
}); 
//监听鼠标动作,click选定 
$(document).delegate('.liketips td','click',function(){ 
    $nowtr=$(this).parent(); 
    if($nowtr.length==1){ 
        //取得该提示层对应的input框 
        $inputfield=$nowtr.parent().parent().parent().siblings('input.getsearchjson'); 
        //设置value值到input框通过参数data-valueto配置的value值存储项中去,一般是hidden项 
        $valuefield=$('input[name='+$inputfield.data('valueto')+']'); 
        $valuefield.val($nowtr.data('value')); 
        $inputfield.val($nowtr.text()); 
        //设置状态是从选项中选择,允许blur 
        $inputfield.data('ok',true); 
    } 
    $(liketips).fadeOut('fast'); 
});

CSS这里就不放出了,我的实现效果如下:

让input框实现类似百度的搜索提示(基于jquery事件监听)

//禁用chrome和firefox浏览器自带的自动提示 
$this.attr("autocomplete","off");
Javascript 相关文章推荐
JavaScript 比较时间大小的代码
Apr 24 Javascript
js解决弹窗问题实现班级跳转DIV示例
Jan 06 Javascript
jquery 字符串切割函数substring的用法说明
Feb 11 Javascript
jquery退出each循环的写法
Feb 26 Javascript
js图片闪动特效可以控制间隔时间如几分钟闪动一下
Aug 12 Javascript
angularjs学习笔记之完整的项目结构
Sep 26 Javascript
JS处理json日期格式化问题
Oct 01 Javascript
利用jquery禁止外层滚动条的滚动
Jan 05 Javascript
常见的浏览器Hack技巧整理
Jun 29 Javascript
Vue之Vue.set动态新增对象属性方法
Feb 23 Javascript
原生JS实现前端本地文件上传
Sep 08 Javascript
手写Spirit防抖函数underscore和节流函数lodash
Mar 22 Javascript
js实现俄罗斯方块小游戏分享
Jan 31 #Javascript
获取select元素被选中的文本内容的js代码
Jan 29 #Javascript
使用POST方式弹出窗口的两种方法示例介绍
Jan 29 #Javascript
qq悬浮代码(兼容各个浏览器)
Jan 29 #Javascript
js输出阴历、阳历、年份、月份、周示例代码
Jan 29 #Javascript
js跳转页面方法总结
Jan 29 #Javascript
Asp.Net alert弹出提示信息的几种方法总结
Jan 29 #Javascript
You might like
php打造属于自己的MVC框架
2012/03/07 PHP
在IIS下安装PHP扩展的方法(超简单)
2017/04/10 PHP
Ajax中的JSON格式与php传输过程全面解析
2017/11/14 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
Javascript里使用Dom操作Xml
2006/09/20 Javascript
jquery tools之tooltip
2009/07/25 Javascript
javascript操作table(insertRow,deleteRow,insertCell,deleteCell方法详解)
2013/12/16 Javascript
快速解决jquery之get缓存问题的最简单方法介绍
2013/12/19 Javascript
js获取下拉列表框中的value和text的值示例代码
2014/01/11 Javascript
JQuery异步加载无限下拉框级联功能实现示例
2014/02/19 Javascript
jquery判断小数点两位和自动删除小数两位后的数字
2014/03/19 Javascript
js简单判断flash是否加载完成的方法
2016/06/21 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
Angular.Js之Scope作用域的学习教程
2017/04/27 Javascript
nodejs基于WS模块实现WebSocket聊天功能的方法
2018/01/12 NodeJs
JS中touchstart事件与click事件冲突的解决方法
2018/03/12 Javascript
解决vue热替换失效的根本原因
2018/09/19 Javascript
Smartour 让网页导览变得更简单(推荐)
2019/07/19 Javascript
JavaScript中break、continue和return的用法区别实例分析
2020/03/02 Javascript
vue使用exif获取图片旋转,压缩的示例代码
2020/12/11 Vue.js
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
详解python string类型 bytes类型 bytearray类型
2017/12/16 Python
怎么使用pipenv管理你的python项目
2018/03/12 Python
分析运行中的 Python 进程详细解析
2019/06/22 Python
使用python爬取抖音视频列表信息
2019/07/15 Python
python3连接kafka模块pykafka生产者简单封装代码
2019/12/23 Python
python + selenium 刷B站播放量的实例代码
2020/06/12 Python
Python在后台自动解压各种压缩文件的实现方法
2020/11/10 Python
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
艺术应用与设计个人的自我评价
2013/11/23 职场文书
个人素质的自我评价分享
2013/12/16 职场文书
司法建议书范文
2014/05/13 职场文书
mybatis使用oracle进行添加数据的方法
2021/04/27 Oracle
python实现自动清理文件夹旧文件
2021/05/10 Python
vue实现同时设置多个倒计时
2021/05/20 Vue.js
Jedis操作Redis实现模拟验证码发送功能
2021/09/25 Redis