js输入框邮箱自动提示功能代码实现


Posted in Javascript onDecember 10, 2013

同理 此插件不需要任何html标签,只需要一个输入框 有相对应的class类名就ok 且父级有个class类名,其他的都不需要。内部的HTML代码都是自动生成的。

HTML代码如下:

<div class="parentCls">
    <input type="text" class="inputElem">
 </div>

其实上面的div标签都可以不需要 只需要在input输入框 且父级元素添加一个如上class(自定义也可以,只是在JS初始化的时候要传入class就ok 我默认情况下 父级class叫parentCls,当前输入框class叫inputElem,隐藏域的class叫hiddenCls,在初始化的时候 直接初始化 传入空对象即可!)。因为页面上可能有多个输入框 所以需要一个父级class 来区分是那个输入框,当然要个隐藏域 存值给开发后台。

其中在配置项里面 有个邮箱数组参数 mailArr        : ["@qq.com","@qq2.com","@gmail.com","@126.com","@163.com","@hotmail.com","@yahoo.com","@yahoo.com.cn","@live.com","@sohu.com","@sina.com"] 。就是要告诉我们默认邮箱有这么多,不管我输入什么 下拉框初始化时候有这么多邮箱提示,当我精确到某一项的时候 在给个提示 精确到某一项下拉。当然由于需求的变更 邮箱这个参数可以自己初始化时候 自己根据需求配置。

代码风格还是和以前一样。

实现的功能如下:

1. 支持键盘上下移键盘操作,支持鼠标点击及按回车操作。

2. 点击document时候 除当前input输入框之外 下拉框隐藏。当接着输入时候 实现自动匹配等等操作。

具体不多说 就是类似于网上注册时候 邮箱自动提示功能一样 ,如果有任何bug的话 可以给我留言,时间也不早了 不罗嗦了!直接贴代码:

CSS代码如下:

<style>
   *{margin:0;padding:0;}
   ul,li{list-style:none;}
   .inputElem {width:198px;height:22px;line-height:22px;border:1px solid #ff4455;}
   .parentCls{width:200px;}
   .auto-tip li{width:100%;height:22px;line-height:22px;font-size:14px;}
   .auto-tip li.hoverBg{background:#ddd;cursor:pointer;}
   .red{color:red;}
   .hidden {display:none;}
  </style>

JS代码如下:

/**
 * 邮箱自动提示插件
 * @constructor EmailAutoComplete
 * @ options {object} 可配置项
 */
 function EmailAutoComplete(options) {
    this.config = {
        targetCls      :  '.inputElem',       // 目标input元素
        parentCls      :  '.parentCls',       // 当前input元素的父级类
        hiddenCls      :  '.hiddenCls',       // 当前input隐藏域 
        searchForm     :  '.jqtransformdone', //form表单
        hoverBg        :  'hoverBg',          // 鼠标移上去的背景
        inputValColor  :  'red',              // 输入框输入提示颜色
        mailArr        : ["@qq.com","@qq2.com","@gmail.com","@126.com","@163.com","@hotmail.com","@yahoo.com","@yahoo.com.cn","@live.com","@sohu.com","@sina.com"], //邮箱数组
        isSelectHide   : true,                // 点击下拉框 是否隐藏 默认为true
        callback       : null                 // 点击某一项回调函数
    };
    this.cache = {
        onlyFlag            : true,     // 只渲染一次
        currentIndex        : -1,
        oldIndex            : -1
    };
    this.init(options);
 }
EmailAutoComplete.prototype = {
    constructor: EmailAutoComplete,
    init: function(options){
        this.config = $.extend(this.config,options || {});
        var self = this,
            _config = self.config,
            _cache = self.cache;
        $(_config.targetCls).each(function(index,item){
            $(item).keyup(function(e){
                var target = e.target,
                    targetVal = $.trim($(this).val()),
                    keycode = e.keyCode,
                    elemHeight = $(this).outerHeight(),
                    elemWidth = $(this).outerWidth(),
                    parentNode = $(this).closest(_config.parentCls);
                $(parentNode).css({'position':'relative'});
                // 如果输入框值为空的话 那么下拉框隐藏
                if(targetVal == '') {
                    $(item).attr({'data-html':''});
                    // 给隐藏域赋值
                    $(_config.hiddenCls,parentNode).val('');
                    _cache.currentIndex = -1;
                    _cache.oldIndex = -1;
                    $(".auto-tip",parentNode) && !$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
                    self._removeBg(parentNode);
                }else {
                    $(item).attr({'data-html':targetVal});
                    // 给隐藏域赋值
                    $(_config.hiddenCls,parentNode).val(targetVal);
                    $(".auto-tip",parentNode) && $(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).removeClass('hidden');
                    // 渲染下拉框内容
                    self._renderHTML({keycode:keycode,e:e,target:target,targetVal:targetVal,height:elemHeight,width:elemWidth,parentNode:parentNode});
                }
                
            });
        });
       // 阻止form表单默认enter键提交
       $(_config.searchForm).each(function(index,item) {
            $(item).keydown(function(e){
                 var keyCode = e.keyCode;
                 if(keyCode == 13) {
                     return false;
                 }
            });
       });
       // 点击文档document时候 下拉框隐藏掉
       $(document).click(function(e){
          e.stopPropagation();
          var target = e.target,
              tagCls = _config.targetCls.replace(/^\./,'');
          if(!$(target).hasClass(tagCls)) {
             $('.auto-tip') && $('.auto-tip').each(function(index,item){
                 !$(item).hasClass('hidden') && $(item).addClass('hidden');
             });
          }
       });
    },
    /*
     * 渲染下拉框提示内容
     * @param cfg{object}
     */
    _renderHTML: function(cfg) {
        var self = this,
            _config = self.config,
            _cache = self.cache,
            curVal;
        var curIndex = self._keyCode(cfg.keycode);
        $('.auto-tip',cfg.parentNode).hasClass('hidden') && $('.auto-tip',cfg.parentNode).removeClass('hidden');
        if(curIndex > -1){
            // 键盘上下操作
            self._keyUpAndDown(cfg.targetVal,cfg.e,cfg.parentNode);
        }else {
            if(/@/.test(cfg.targetVal)) {
                curVal = cfg.targetVal.replace(/@.*/,'');
            }else {
                curVal = cfg.targetVal;
            }
            if(_cache.onlyFlag) {
                $(cfg.parentNode).append('<input type="hidden" class="hiddenCls"/>');
                var wrap = '<ul class="auto-tip">';
                for(var i = 0; i < _config.mailArr.length; i++) {
                    wrap += '<li class="p-index'+i+'">'+'<span class="output-num"></span><em class="em" data-html="'+_config.mailArr[i]+'">'+_config.mailArr[i]+'</em></li>';
                }
                wrap += '</ul>';
                _cache.onlyFlag = false;
                $(cfg.parentNode).append(wrap);
                $('.auto-tip',cfg.parentNode).css({'position':'absolute','top':cfg.height,'width':cfg.width - 2 + 'px','left':0,
                    'border':'1px solid #ccc','z-index':10000});
            }
            // 给所有li添加属性 data-html
            $('.auto-tip li',cfg.parentNode).each(function(index,item){
                $('.output-num',item).html(curVal);
                !$('.output-num',item).hasClass(_config.inputValColor) && 
                $('.output-num',item).addClass(_config.inputValColor);
                var emVal = $.trim($('.em',item).attr('data-html'));
                $(item).attr({'data-html':curVal + '' +emVal});
            });
            // 精确匹配内容
            self._accurateMate({target:cfg.target,parentNode:cfg.parentNode});
            // 鼠标移到某一项li上面时候
            self._itemHover(cfg.parentNode);
            // 点击对应的项时
            self._executeClick(cfg.parentNode);
        }
    },
    /**
     * 精确匹配某项内容
     */
    _accurateMate: function(cfg) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        var curVal = $.trim($(cfg.target,cfg.parentNode).attr('data-html')),
            newArrs = [];
        if(/@/.test(curVal)) {
            // 获得@ 前面 后面的值
            var prefix = curVal.replace(/@.*/, ""),
                suffix = curVal.replace(/.*@/, "");
            $.map(_config.mailArr,function(n){
                var reg = new RegExp(suffix);
                if(reg.test(n)) {
                    newArrs.push(n);
                }
            });
            if(newArrs.length > 0) {
                $('.auto-tip',cfg.parentNode).html('');
                $(".auto-tip",cfg.parentNode) && $(".auto-tip",cfg.parentNode).hasClass('hidden') && 
                $(".auto-tip",cfg.parentNode).removeClass('hidden');
                var html = '';
                for(var j = 0, jlen = newArrs.length; j < jlen; j++) {
                    html += '<li class="p-index'+j+'">'+'<span class="output-num"></span><em class="em" data-html="'+newArrs[j]+'">'+newArrs[j]+'</em></li>';
                }
                $('.auto-tip',cfg.parentNode).html(html);
                // 给所有li添加属性 data-html
                $('.auto-tip li',cfg.parentNode).each(function(index,item){
                    $('.output-num',item).html(prefix);
                    !$('.output-num',item).hasClass(_config.inputValColor) && 
                    $('.output-num',item).addClass(_config.inputValColor);
                    var emVal = $.trim($('.em',item).attr('data-html'));
                    $(item).attr('data-html','');
                    $(item).attr({'data-html':prefix + '' +emVal});
                });
                // 精确匹配到某项时候 让当前的索引等于初始值
                _cache.currentIndex = -1;
                _cache.oldIndex = -1;
                $('.auto-tip .output-num',cfg.parentNode).html(prefix);
                // 鼠标移到某一项li上面时候
                self._itemHover(cfg.parentNode);
                // 点击对应的项时
                self._executeClick(cfg.parentNode);
            }else {
                $(".auto-tip",cfg.parentNode) && !$(".auto-tip",cfg.parentNode).hasClass('hidden') && 
                $(".auto-tip",cfg.parentNode).addClass('hidden');
                $('.auto-tip',cfg.parentNode).html('');
            }
        }
    },
    /*
     * 鼠标移到某一项li上时
     */
    _itemHover: function(parentNode) {
        var self = this,
            _config = self.config,
            _cache = self.cache;
        $('.auto-tip li',parentNode).hover(function(index,item) {
            !$(this).hasClass(_config.hoverBg) && $(this).addClass(_config.hoverBg);
        },function() {
            $(this).hasClass(_config.hoverBg) && $(this).removeClass(_config.hoverBg);
        });
    },
    /*
     * 当输入框值为空时候 li项都删掉class hoverBg
     */
    _removeBg: function(parentNode){
        var self = this,
            _config = self.config;
        $(".auto-tip li",parentNode).each(function(index,item){
            $(item).hasClass(_config.hoverBg) && $(item).removeClass(_config.hoverBg);
        });    
    },
    /**
     * 键盘上下键操作
     */
     _keyUpAndDown: function(targetVal,e,parentNode) {
        var self = this,
            _cache = self.cache,
            _config = self.config;
        // 如果请求成功后 返回了数据(根据元素的长度来判断) 执行以下操作
        if($('.auto-tip' + ' li',parentNode) && $('.auto-tip' + ' li').length > 0) {
            var plen = $('.auto-tip' + ' li',parentNode).length,
                keyCode = e.keyCode;
                _cache.oldIndex = _cache.currentIndex;
            
            // 上移操作
            if(keyCode == 38) {
                if(_cache.currentIndex == -1) {
                    _cache.currentIndex = plen - 1;
                }else {
                    _cache.currentIndex = _cache.currentIndex - 1;
                    if(_cache.currentIndex < 0) {
                        _cache.currentIndex = plen - 1;
                    }
                }
                if(_cache.currentIndex !== -1) {
                    
                    !$('.auto-tip .p-index'+_cache.currentIndex,parentNode).hasClass(_config.hoverBg) &&
                    $('.auto-tip .p-index'+_cache.currentIndex,parentNode).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                    var curAttr = $('.auto-tip' + ' .p-index'+_cache.currentIndex,parentNode).attr('data-html');
                    $(_config.targetCls,parentNode).val(curAttr);
                    // 给隐藏域赋值
                    $(_config.hiddenCls,parentNode).val(curAttr);
                }
            }else if(keyCode == 40) { //下移操作
                if(_cache.currentIndex == plen - 1) {
                    _cache.currentIndex = 0;
                }else {
                    _cache.currentIndex++;
                    if(_cache.currentIndex > plen - 1) {
                        _cache.currentIndex = 0;
                    }
                }
                if(_cache.currentIndex !== -1) {
                    !$('.auto-tip .p-index'+_cache.currentIndex,parentNode).hasClass(_config.hoverBg) &&
                    $('.auto-tip .p-index'+_cache.currentIndex,parentNode).addClass(_config.hoverBg).siblings().removeClass(_config.hoverBg);
                    var curAttr = $('.auto-tip' + ' .p-index'+_cache.currentIndex,parentNode).attr('data-html');
                    $(_config.targetCls,parentNode).val(curAttr);
                    // 给隐藏域赋值
                    $(_config.hiddenCls,parentNode).val(curAttr);
                }
            }else if(keyCode == 13) { //回车操作
                var curVal = $('.auto-tip' + ' .p-index'+_cache.oldIndex,parentNode).attr('data-html');
                $(_config.targetCls,parentNode).val(curVal);
                // 给隐藏域赋值
                $(_config.hiddenCls,parentNode).val(curVal);
                if(_config.isSelectHide) {
                     !$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
                 }
                 _config.callback && $.isFunction(_config.callback) && _config.callback();
                _cache.currentIndex = -1;
                _cache.oldIndex = -1;
            }
        }
     },
     _keyCode: function(code) {
         var arrs = ['17','18','38','40','37','39','33','34','35','46','36','13','45','44','145','19','20','9'];
         for(var i = 0, ilen = arrs.length; i < ilen; i++) {
             if(code == arrs[i]) {
                 return i;
             }
         }
         return -1;
     },
    /**
      * 当数据相同的时 点击对应的项时 返回数据
      */
     _executeClick: function(parentNode) {
         var _self = this,
             _config = _self.config;
         $('.auto-tip' + ' li',parentNode).unbind('click');
         $('.auto-tip' + ' li',parentNode).bind('click',function(e){
              var dataAttr = $(this).attr('data-html');
              $(_config.targetCls,parentNode).val(dataAttr);
              if(_config.isSelectHide) {
                  !$(".auto-tip",parentNode).hasClass('hidden') && $(".auto-tip",parentNode).addClass('hidden');
              }
              // 给隐藏域赋值
              $(_config.hiddenCls,parentNode).val(dataAttr);
              _config.callback && $.isFunction(_config.callback) && _config.callback();
         });
     }
};
// 初始化
$(function() {
    new EmailAutoComplete({});
});
Javascript 相关文章推荐
Prototype1.6 JS 官方下载地址
Nov 30 Javascript
jQuery学习笔记之DOM对象和jQuery对象
Dec 22 Javascript
理解jQuery stop()方法
Nov 21 Javascript
ECMAScript5(ES5)中bind方法使用小结
May 07 Javascript
JavaScript事件类型中UI事件详解
Jan 14 Javascript
JS触摸屏网页版仿app弹窗型滚动列表选择器/日期选择器
Oct 30 Javascript
webpack学习笔记之优化缓存、合并、懒加载
Aug 24 Javascript
JavaScript实现开关等效果
Sep 08 Javascript
在微信小程序中使用vant的方法
Jun 07 Javascript
p5.js实现动态图形临摹
Oct 23 Javascript
Vue性能优化的方法
Jul 30 Javascript
vue使用exif获取图片经纬度的示例代码
Dec 11 Vue.js
浅析jQuery1.8的几个小变化
Dec 10 #Javascript
Javascript中各种trim的实现详细解析
Dec 10 #Javascript
深入理解Javascript动态方法调用与参数修改的问题
Dec 10 #Javascript
ExtJS的拖拽效果示例
Dec 09 #Javascript
用Javascript获取页面元素的具体位置
Dec 09 #Javascript
jQuery取得select选择的文本与值的示例
Dec 09 #Javascript
JavaScript—window对象使用示例
Dec 09 #Javascript
You might like
SONY ICF-SW55的电路分析
2021/03/02 无线电
for循环连续求和、九九乘法表代码
2012/02/20 PHP
浅谈PHP值mysql操作类
2016/06/29 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
基于PHP实现微信小程序客服消息功能
2019/08/12 PHP
Laravel 5.1 框架Blade模板引擎用法实例分析
2020/01/04 PHP
使用prototype.js进行异步操作
2007/02/07 Javascript
javascript之对系统的toFixed()方法的修正
2007/05/08 Javascript
javascript对select标签的控制(option选项/select)
2013/01/31 Javascript
jquery表单对象属性过滤选择器实例分析
2015/05/18 Javascript
微信小程序学习(4)-系统配置app.json详解
2017/01/12 Javascript
js案例之鼠标跟随jquery版(实例讲解)
2017/07/21 jQuery
vue src动态加载请求获取图片的方法
2018/10/17 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
layui表格分页 记录勾选的实例
2019/09/02 Javascript
[04:10]DOTA2英雄梦之声_第11期_圣堂刺客
2014/06/21 DOTA
Python读写配置文件的方法
2015/06/03 Python
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
对python的输出和输出格式详解
2018/12/08 Python
对Python _取log的几种方式小结
2019/07/25 Python
python multiprocessing模块用法及原理介绍
2019/08/20 Python
matplotlib部件之套索Lasso的使用
2021/02/24 Python
HTML5的结构和语义(3):语义性的块级元素
2008/10/17 HTML / CSS
HTML5和以前HTML4的区别整理
2013/10/20 HTML / CSS
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
次世代生活态度:Hypebeast
2018/07/05 全球购物
不用游标的SQL语句有哪些
2012/09/07 面试题
医学生实习自我鉴定
2013/09/27 职场文书
优秀毕业生自我鉴定
2014/01/19 职场文书
计算机专业毕业生自荐信范文
2014/03/06 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
教师见习总结范文
2015/06/23 职场文书
消夏晚会主持词
2015/06/30 职场文书
竞聘开场白方式有哪些?
2019/08/28 职场文书
海弦WR-800F
2022/04/05 无线电