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 相关文章推荐
JS Replace()的高级使用方法介绍
Jun 29 Javascript
悬浮数字的实现案例
Feb 19 Javascript
JQuery 实现在同一页面锚点链接之间的平滑滚动
Oct 29 Javascript
JavaScript几种数组去掉重复值的方法推荐
Apr 12 Javascript
清除输入框内的空格
Dec 21 Javascript
JS实现的简单轮播图运动效果示例
Dec 22 Javascript
简单实现IONIC购物车功能
Jan 10 Javascript
在 Angular6 中使用 HTTP 请求服务端数据的步骤详解
Aug 06 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
Aug 24 Javascript
小程序实现多选框功能
Oct 30 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
微信小程序实现录制、试听、上传音频功能(带波形图)
Feb 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
php4的session功能评述(三)
2006/10/09 PHP
php数组使用规则分析
2015/02/27 PHP
PHP处理数组和XML之间的互相转换
2016/06/02 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
laravel 实现划分admin和home 模块分组
2019/10/15 PHP
jquery一般方法介绍 入门参考
2011/06/21 Javascript
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
jquery中文乱码的多种解决方法
2013/06/21 Javascript
JS+CSS实现的经典圆角下拉菜单效果代码
2015/10/21 Javascript
vue微信分享 vue实现当前页面分享其他页面
2017/12/02 Javascript
代码详解Vuejs响应式原理
2017/12/20 Javascript
JavaScript的数据类型转换原则(干货)
2018/03/15 Javascript
jQuery实现的电子时钟效果完整示例
2018/04/28 jQuery
小程序新版订阅消息模板消息
2019/12/31 Javascript
微信小程序入门之绘制时钟
2020/10/22 Javascript
基于JavaScript实现简单的轮播图
2021/03/03 Javascript
使用Python+Splinter自动刷新抢12306火车票
2018/01/03 Python
Python利用字典将两个通讯录文本合并为一个文本实例
2018/01/16 Python
pyspark 读取csv文件创建DataFrame的两种方法
2018/06/07 Python
用python打印1~20的整数实例讲解
2019/07/01 Python
python简单区块链模拟详解
2019/07/03 Python
python生成器用法实例详解
2019/11/22 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
CSS3 Flexbox中flex-shrink属性的用法示例介绍
2013/12/30 HTML / CSS
windeln官方海外旗舰店:德淘超人气母婴超市
2017/12/15 全球购物
环保倡议书50字
2014/05/15 职场文书
党员群众路线个人整改措施思想汇报
2014/10/12 职场文书
2014公司年终工作总结
2014/12/19 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
个人党性分析总结
2015/03/05 职场文书
总经理岗位职责范本
2015/04/01 职场文书
2015年幼儿园班务工作总结
2015/05/12 职场文书
如何撰写促销方案?
2019/07/05 职场文书
创业计划书之家教托管
2019/09/25 职场文书
mysql自增长id用完了该怎么办
2022/02/12 MySQL
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android