让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的eval()中使用函数的进一步讨论
Jul 26 Javascript
location.href语句与火狐不兼容的问题
Jul 04 Javascript
JS兼容浏览器的导出Excel(CSV)文件的方法
May 03 Javascript
javascript 兼容各个浏览器的事件
Feb 04 Javascript
JavaScript中String.prototype用法实例
May 20 Javascript
javascript中的Function.prototye.bind
Jun 25 Javascript
JavaScript对数组进行随机重排的方法
Jul 22 Javascript
js阻止浏览器默认行为的简单实例
May 15 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
使用vue编写一个点击数字计时小游戏
Aug 31 Javascript
Angular5中调用第三方库及jQuery的添加的方法
Jun 07 jQuery
Vue如何使用混合Mixins和插件开发详解
Feb 05 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实现带读写分离功能的MySQL类完整实例
2016/07/28 PHP
php生成网页桌面快捷方式
2017/05/05 PHP
PHP实现将标点符号正则替换为空格的方法
2017/08/09 PHP
PHP number_format函数原理及实例解析
2020/07/14 PHP
判断控件是否已加载完成的代码
2010/02/24 Javascript
JS函数重载的解决方案
2014/05/13 Javascript
js实现同一个页面多个渐变效果的方法
2015/04/10 Javascript
jQuery实现判断滚动条到底部
2015/06/23 Javascript
JS模式之单例模式基本用法
2015/06/30 Javascript
jquery实现动画菜单的左右滚动、渐变及图形背景滚动等效果
2015/08/25 Javascript
js实现具有高亮显示效果的多级菜单代码
2015/09/01 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
Vue.js自定义指令的用法与实例解析
2017/01/18 Javascript
js实现移动端编辑添加地址【模仿京东】
2017/04/28 Javascript
Node.js中DNS模块学习总结
2018/02/28 Javascript
jquery获取input输入框中的值
2019/11/13 jQuery
vue使用nprogress实现进度条
2019/12/09 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
对django xadmin自定义菜单的实例详解
2019/01/03 Python
对python使用telnet实现弱密码登录的方法详解
2019/01/26 Python
python爬取酷狗音乐排行榜
2019/02/20 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
2019/11/29 Python
python实现简单的五子棋游戏
2020/09/01 Python
python dir函数快速掌握用法技巧
2020/12/09 Python
大韩航空官方网站:Korean Air
2017/10/25 全球购物
Noon埃及:埃及在线购物
2019/11/26 全球购物
德国高尔夫商店:Par71.de
2020/11/29 全球购物
汉语言文学毕业生求职信
2013/10/01 职场文书
大学新生入学教育方案
2014/05/16 职场文书
开发房地产协议书
2014/09/14 职场文书
教师文明餐桌光盘行动倡议书
2015/04/28 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
七年级写作指导之游记作文
2019/10/07 职场文书
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技