让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 css在IE和Firefox中区别分析
Feb 18 Javascript
jquery入门—数据删除与隔行变色以及图片预览
Jan 07 Javascript
javascript使用定时函数实现跳转到某个页面
Dec 25 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
Mar 21 Javascript
javascript定时器完整实例
Feb 10 Javascript
纯javascript实现图片延时加载方法
Aug 21 Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
Feb 06 Javascript
基于javascript实现表格的简单操作
May 21 Javascript
浅谈javascript中的数据类型转换
Dec 27 Javascript
js绑定事件和解绑事件
Apr 27 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
vue3中的组件间通信
Mar 31 Vue.js
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调用Oracle存储过程的方法
2008/09/12 PHP
PHP面向对象的进阶学习(抽像类、接口、final、类常量)
2012/05/07 PHP
全面解析PHP面向对象的三大特征
2017/06/10 PHP
JavaScript脚本性能的优化方法
2007/02/02 Javascript
JavaScript中的History历史对象
2008/01/16 Javascript
js如何实现淡入淡出效果
2020/11/18 Javascript
javascript性能优化之DOM交互操作实例分析
2015/12/12 Javascript
JavaScript记录光标在编辑器中位置的实现方法
2016/04/22 Javascript
jQuery原理系列-css选择器的简单实现
2016/06/07 Javascript
JS采用绝对定位实现回到顶部效果完整实例
2016/06/20 Javascript
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
2016/07/26 NodeJs
Angular客户端请求Rest服务跨域问题的解决方法
2017/09/19 Javascript
Vue工程模板文件 webpack打包配置方法
2017/12/26 Javascript
详解vue 数组和对象渲染问题
2018/09/21 Javascript
Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
2019/08/23 Javascript
微信小程序授权登陆及每次检查是否授权实例代码
2019/09/18 Javascript
Vue+axios封装请求实现前后端分离
2020/10/23 Javascript
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
人工神经网络算法知识点总结
2019/06/11 Python
使用python 写一个静态服务(实战)
2019/06/28 Python
解决Python对齐文本字符串问题
2019/08/28 Python
如何利用pygame实现简单的五子棋游戏
2019/12/29 Python
python+selenium+Chrome options参数的使用
2020/03/18 Python
Python爬虫谷歌Chrome F12抓包过程原理解析
2020/06/04 Python
解决Python 写文件报错TypeError的问题
2020/10/23 Python
大专生自荐信
2013/10/04 职场文书
网站编辑求职信
2013/10/17 职场文书
培训楼经理岗位责任制
2014/02/10 职场文书
《小白兔和小灰兔》教学反思
2014/02/18 职场文书
授权委托书(完整版)
2014/09/10 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
英语教师个人工作总结
2015/02/09 职场文书
学校运动会开幕词
2016/03/03 职场文书
Javascript中async与await的捕捉错误详解
2022/03/03 Javascript
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server