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 动态选中下拉框
Nov 26 Javascript
jQuery实现滚动切换的tab选项卡效果代码
Aug 26 Javascript
JS+CSS实现的漂亮渐变背景特效代码(6个渐变效果)
Mar 25 Javascript
bootstrap下拉列表与输入框组结合的样式调整
Oct 08 Javascript
vue使用drag与drop实现拖拽的示例代码
Sep 07 Javascript
使用watch监听路由变化和watch监听对象的实例
Feb 24 Javascript
微信小程序如何获取手机验证码
Nov 04 Javascript
详解Angular模板引用变量及其作用域
Nov 23 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
Sep 28 Javascript
javascript实现前端成语点击验证优化
Jun 24 Javascript
Element Dialog对话框的使用示例
Jul 26 Javascript
详解阿里Node.js技术文档之process模块学习指南
Jan 04 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操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
jquery load()在firefox(火狐)下显示不正常的解决方法
2011/04/05 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
2013/05/08 Javascript
jquery图片放大功能简单实现
2013/08/01 Javascript
使用nodejs、Python写的一个简易HTTP静态文件服务器
2014/07/18 NodeJs
javaScript事件学习小结(四)event的公共成员(属性和方法)
2016/06/09 Javascript
javascript验证手机号和实现星号(*)代替实例
2016/08/16 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
JavaScript根据json生成html表格的示例代码
2018/10/24 Javascript
vue插件draggable实现拖拽移动图片顺序
2018/12/01 Javascript
如何利用node.js开发一个生成逐帧动画的小工具
2019/12/01 Javascript
js get和post请求实现代码解析
2020/02/06 Javascript
[46:09]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第三场
2014/05/26 DOTA
[02:30]辉夜杯主赛事第二日胜者组半决赛 CDEC.Y赛后采访
2015/12/26 DOTA
[44:01]2018DOTA2亚洲邀请赛3月30日 小组赛B组 EG VS paiN
2018/03/31 DOTA
动态创建类实例代码
2009/10/07 Python
[原创]教女朋友学Python(一)运行环境搭建
2017/11/29 Python
Python基于Floyd算法求解最短路径距离问题实例详解
2018/05/16 Python
python3.5绘制随机漫步图
2018/08/27 Python
python如何获取当前文件夹下所有文件名详解
2019/01/25 Python
numpy.random模块用法总结
2019/05/27 Python
Python学习笔记之读取文件、OS模块、异常处理、with as语法示例
2019/06/04 Python
Python实用工具FuckIt.py介绍
2019/07/02 Python
Python调用REST API接口的几种方式汇总
2020/10/19 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
纯CSS3实现Material Design效果
2017/03/09 HTML / CSS
日本小田急百货官网:Odakyu
2018/07/19 全球购物
芬兰设计商店美国:Finnish Design Shop US
2019/03/25 全球购物
*p++ 自增p 还是p所指向的变量
2016/07/16 面试题
KTV员工管理制度
2015/08/06 职场文书
小学生安全教育主题班会
2015/08/12 职场文书
2016年员工政治思想表现评语
2015/12/02 职场文书
详解Redis主从复制实践
2021/05/19 Redis
Java中CyclicBarrier和CountDownLatch的用法与区别
2021/08/23 Java/Android
漫画《催眠麦克风-Dawn Of Divisions》第二卷PV公开
2022/04/05 日漫