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 相关文章推荐
JavaScript下利用fso判断文件是否存在的代码
Dec 11 Javascript
js对图片base64编码字符串进行解码并输出图像示例
Mar 17 Javascript
javascript用函数实现对象的方法
May 14 Javascript
完善的jquery处理机制
Feb 21 Javascript
JS中创建函数的三种方式及区别
Mar 13 Javascript
KnockoutJS 3.X API 第四章之表单value绑定
Oct 10 Javascript
vue打包后显示空白正确处理方法
Nov 01 Javascript
mint-ui在vue中的使用示例
Apr 05 Javascript
vue-cli 组件的导入与使用教程详解
Apr 11 Javascript
bootstrap中的导航条实例代码详解
May 20 Javascript
jQuery 选择方法及$(this)用法实例分析
May 19 jQuery
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
Aug 27 Javascript
浅析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
php循环输出数据库内容的代码
2008/05/24 PHP
php与paypal整合方法
2010/11/28 PHP
PHP读MYSQL中文乱码的快速解决方法
2016/10/01 PHP
laravel框架中间件 except 和 only 的用法示例
2019/07/12 PHP
Thinkphp5框架简单实现钩子(Hook)行为的方法示例
2019/09/03 PHP
客户端js判断文件类型和文件大小即限制上传大小
2013/11/20 Javascript
jQuery使用fadein方法实现渐出效果实例
2015/03/27 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
jquery ztree实现树的搜索功能
2016/02/25 Javascript
JavaScript实现Java中Map容器的方法
2016/10/09 Javascript
js实现可旋转的立方体模型
2016/10/16 Javascript
angular仿支付宝密码框输入效果
2017/03/25 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
vue中路由参数传递可能会遇到的坑
2017/12/07 Javascript
微信小程序实现笑脸评分功能
2018/11/03 Javascript
详解微信小程序-扫一扫 wx.scanCode() 扫码大变身
2019/04/30 Javascript
分享一个vue项目“脚手架”项目的实现步骤
2019/05/26 Javascript
vue 中 命名视图的用法实例详解
2019/08/14 Javascript
javascript canvas API内容整理
2020/02/16 Javascript
python Django的web开发实例(入门)
2019/07/31 Python
python多线程并发及测试框架案例
2019/10/15 Python
关于pytorch中全连接神经网络搭建两种模式详解
2020/01/14 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
利用OpenCV中对图像数据进行64F和8U转换的方式
2020/06/03 Python
python基本算法之实现归并排序(Merge sort)
2020/09/01 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
Canvas制作旋转的太极的示例
2018/03/09 HTML / CSS
史泰博(Staples)中国官方网站:办公用品一站式采购
2016/09/05 全球购物
哈萨克斯坦最大的时装、鞋子和配饰在线商店:Lamoda.kz
2019/11/19 全球购物
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
森林防火宣传标语
2014/06/27 职场文书
治庸问责心得体会
2014/09/12 职场文书
法院个人总结
2015/03/03 职场文书
2019关于垃圾分类处理的调查报告
2019/12/26 职场文书
CSS3中Animation实现简单的手指点击动画的示例
2021/07/15 HTML / CSS
Win11如何设置右键单击显示所有选项?Win11右键单击显示所有选项设置教程
2022/04/08 数码科技