让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 相关文章推荐
jQuery 操作下拉列表框实现代码
Feb 22 Javascript
当某个文本框成为焦点时即清除文本框内容
Apr 28 Javascript
jQuery实现简单隔行变色的方法
Feb 20 Javascript
判断输入的字符串是否是日期格式的简单方法
Jul 11 Javascript
jQuery实现Select左右复制移动内容
Aug 05 Javascript
一个简易时钟效果js实现代码
Mar 25 Javascript
全新打包工具parcel零配置vue开发脚手架
Jan 11 Javascript
koa socket即时通讯的示例代码
Sep 07 Javascript
分享5个顶级的JavaScript Ajax组件库
Sep 16 Javascript
Vue CLI3移动端适配(px2rem或postcss-plugin-px2rem)
Apr 27 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
Jul 09 Javascript
JS实现数组去重的11种方法总结
Apr 04 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
德生S2000电路分析
2021/03/02 无线电
WordPress中自定义后台管理界面配色方案的小技巧
2015/12/29 PHP
详解WordPress中分类函数wp_list_categories的使用
2016/01/04 PHP
PHP实现数据库的增删查改功能及完整代码
2018/04/18 PHP
PHP封装的验证码工具类定义与用法示例
2018/08/22 PHP
Function.prototype.bind用法示例
2013/09/16 Javascript
判断输入是否为空,获得输入类型的JS代码
2013/10/30 Javascript
JS实现超简单的仿QQ折叠菜单效果
2015/09/21 Javascript
Java遍历集合方法分析(实现原理、算法性能、适用场合)
2016/04/25 Javascript
AngularJS实现textarea记录只能输入规定数量的字符并显示
2016/04/26 Javascript
快速使用Bootstrap搭建传送带
2016/05/06 Javascript
原生js实现tab选项卡切换
2020/03/23 Javascript
js初始化验证实例详解
2016/11/26 Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
2018/01/03 Javascript
更改BootStrap popover的默认样式及popover简单用法
2018/09/13 Javascript
微信小程序开发实现的IP地址查询功能示例
2019/03/28 Javascript
vue.js中ref及$refs的使用方法解析
2019/10/08 Javascript
Node 模块原理与用法详解
2020/05/13 Javascript
在vue中通过render函数给子组件设置ref操作
2020/11/17 Vue.js
[38:30]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第一场2
2014/05/24 DOTA
Python Tkinter GUI编程入门介绍
2015/03/10 Python
Python多继承顺序实例分析
2018/05/26 Python
使用Filter过滤python中的日志输出的实现方法
2019/07/17 Python
Django 路由控制的实现
2019/07/17 Python
浅谈Python中re.match()和re.search()的使用及区别
2020/04/14 Python
Python Selenium XPath根据文本内容查找元素的方法
2020/12/07 Python
可自定义箭头样式的CSS3气泡提示框
2016/03/16 HTML / CSS
美国最大婚纱连锁店运营商:David’s Bridal
2019/03/12 全球购物
英国奢侈品概念店:Base Blu
2019/05/16 全球购物
英国哈罗德园艺:Harrod Horticultural
2020/03/31 全球购物
Fanatics官网:运动服装、球衣、运动装备
2020/10/12 全球购物
村官学习十八大感想
2014/01/15 职场文书
护士岗位职责
2014/02/16 职场文书
保护野生动物倡议书
2014/05/16 职场文书
2015年学校后勤工作总结
2015/04/08 职场文书
小区保洁员岗位职责
2015/04/10 职场文书