jquery 实现输入邮箱时自动补全下拉提示功能


Posted in Javascript onOctober 04, 2015

记得去年做某个项目的时候,用到了邮箱输入自动提示功能,于是网上搜了一下,发现了这个写得不错,现在回想起来,转载一下,方便查阅。

邮箱的广泛使用得益于它的免费,因此很多网站在注册的时候都会直接使用邮箱作为账号名

为了提高用户的体验,很多网站都会实现邮箱输入的自动提示功能。

实现效果如图所示:

核心代码(需要jquery的支持):

(function($){
  $.fn.mailAutoComplete = function(options){
    var defaults = {
      boxClass: "mailListBox", //外部box样式
      listClass: "mailListDefault", //默认的列表样式
      focusClass: "mailListFocus", //列表选样式中
      markCalss: "mailListHlignt", //高亮样式
      zIndex: 1,
      autoClass: true, //是否使用插件自带class样式
      mailArr: ["qq.com","gmail.com","126.com","163.com","hotmail.com","yahoo.com","yahoo.com.cn","live.com","sohu.com","sina.com"], //邮件数组
      textHint: false, //文字提示的自动显示与隐藏
      hintText: "",
      focusColor: "#333"
      //blurColor: "#999"
    };
    var settings = $.extend({}, defaults, options || {});
    
    //页面装载CSS样式
    if(settings.autoClass && $("#mailListAppendCss").size() === 0){
      $('<style id="mailListAppendCss" type="text/css">.mailListBox{border:1px solid #369; background:#fff; font:12px/20px Arial;}.mailListDefault{padding:0 5px;cursor:pointer;white-space:nowrap;}.mailListFocus{padding:0 5px;cursor:pointer;white-space:nowrap;background:#369;color:white;}.mailListHlignt{color:red;}.mailListFocus .mailListHlignt{color:#fff;}</style>').appendTo($("head"));  
    }
    var cb = settings.boxClass, cl = settings.listClass, cf = settings.focusClass, cm = settings.markCalss; //插件的class变量
    var z = settings.zIndex, newArr = mailArr = settings.mailArr, hint = settings.textHint, text = settings.hintText, fc = settings.focusColor, bc = settings.blurColor;
    //创建邮件内部列表内容
    $.createHtml = function(str, arr, cur){
      var mailHtml = "";
      if($.isArray(arr)){
        $.each(arr, function(i, n){
          if(i === cur){
            mailHtml += '<div class="mailHover '+cf+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';  
          }else{
            mailHtml += '<div class="mailHover '+cl+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';  
          }
        });
      }
      return mailHtml;
    };
    //一些全局变量
    var index = -1, s;
    $(this).each(function(){
      var that = $(this), i = $(".justForJs").size();  
      if(i > 0){ //只绑定一个文本框
         return;  
      }
      var w = that.outerWidth(), h = that.outerHeight(); //获取当前对象(即文本框)的宽高
      //样式的初始化
      that.wrap('<span style="display:inline-block;position:relative;"></span>')
        .before('<div id="mailListBox_'+i+'" class="justForJs '+cb+'" style="min-width:'+w+'px;_width:'+w+'px;position:absolute;left:-6000px;top:'+h+'px;z-index:'+z+';"></div>');
      var x = $("#mailListBox_" + i), liveValue; //列表框对象
      that.focus(function(){
        //父标签的层级
        $(this).css("color", fc).parent().css("z-index", z);  
        //提示文字的显示与隐藏
        if(hint && text){
          var focus_v = $.trim($(this).val());
          if(focus_v === text){
            $(this).val("");
          }
        }
        //键盘事件
        $(this).keyup(function(e){
          s = v = $.trim($(this).val());  
          if(/@/.test(v)){
            s = v.replace(/@.*/, "");
          }
          if(v.length > 0){
            //如果按键是上下键
            if(e.keyCode === 38){
              //向上
              if(index <= 0){
                index = newArr.length;  
              }
              index--;
            }else if(e.keyCode === 40){
              //向下
              if(index >= newArr.length - 1){
                index = -1;
              }
              index++;
            }else if(e.keyCode === 13){
              //回车
              if(index > -1 && index < newArr.length){
                //如果当前有激活列表
                $(this).val($("#mailList_"+index).text());  
              }
            }else{
              if(/@/.test(v)){
                index = -1;
                //获得@后面的值
                //s = v.replace(/@.*/, "");
                //创建新匹配数组
                var site = v.replace(/.*@/, "");
                newArr = $.map(mailArr, function(n){
                  var reg = new RegExp(site);  
                  if(reg.test(n)){
                    return n;  
                  }
                });
              }else{
                newArr = mailArr;
              }
            }
            x.html($.createHtml(s, newArr, index)).css("left", 0);
            if(e.keyCode === 13){
              //回车
              if(index > -1 && index < newArr.length){
                //如果当前有激活列表
                x.css("left", "-6000px");  
              }
            }
          }else{
            x.css("left", "-6000px");  
          }
        }).blur(function(){
          if(hint && text){
            var blur_v = $.trim($(this).val());
            if(blur_v === ""){
              $(this).val(text);
            }
          }
          $(this).css("color", bc).unbind("keyup").parent().css("z-index",0);
          x.css("left", "-6000px");  
          
        });  
        //鼠标经过列表项事件
        //鼠标经过
        $(".mailHover").live("mouseover", function(){
          index = Number($(this).attr("id").split("_")[1]);  
          liveValue = $("#mailList_"+index).text();
          x.children("." + cf).removeClass(cf).addClass(cl);
          $(this).addClass(cf).removeClass(cl);
        });
      });

      x.bind("mousedown", function(){
        that.val(liveValue);    
      });
    });
  };
  
})(jQuery);

html示例:

<div class="reg_lin1">
<div class="lin1_1">常用邮箱:</div>
<div class="lin1_2"><input type="text" class = "reg_text" id = "email" name = "email"/></div>
<div class="lin1_3"></div>
</div>

调用的jquery代码:

$("#email").mailAutoComplete({
boxClass: "out_box", //外部box样式
listClass: "list_box", //默认的列表样式
focusClass: "focus_box", //列表选样式中
markCalss: "mark_box", //高亮样式
autoClass: false,
textHint: true //提示文字自动隐藏
});

css,这大家自己修改成自己想要的色调

<style type="text/css">
    .out_box{border:1px solid #ccc; background:#fff; font:12px/20px Tahoma;}
    .list_box{border-bottom:1px solid #eee; padding:0 5px; cursor:pointer;}
    .focus_box{background:#f0f3f9;}
    .mark_box{color:#c00;}
  </style>

效果二:

1、此插件为宽度自适应的,也就是当内部文字过长时,外部的div会宽度自动延伸的。在自定义CSS时如果设置了宽度值,则在非IE6浏览器下,宽度自适应失效;
2、无需在样式中为最外部的box设置position属性,或是宽度及高度,这些工作jQuery 插件已经帮你完成,设置了这些属性反而不利于效果的展现;
3、此插件只能使用在单行文本框上,由于未对其他标签类型的元素做限制,所以如果绑定对象不正确,可能会出现一些意想不到的情况.
4.欢迎在使用中提出各种问题和bug.
--------------------------------------------
注:使用方法
CSS代码:

.out_box{border:1px solid #ccc; background:#fff; font:12px/20px Tahoma;}
.list_box{border-bottom:1px solid #eee; padding:0 5px; cursor:pointer;}
.focus_box{background:#f0f3f9;}
.mark_box{color:#c00;}

JS代码:

$("#customTest").mailAutoComplete({
  boxClass: "out_box", //外部box样式
  listClass: "list_box", //默认的列表样式
  focusClass: "focus_box", //列表选样式中
  markCalss: "mark_box", //高亮样式
  autoClass: false,
  textHint: true, //提示文字自动隐藏
  hintText: "请输入邮箱地址"
});
(function($){
  $.fn.mailAutoComplete = function(options){
    var defaults = {
      boxClass: "mailListBox", //外部box样式
      listClass: "mailListDefault", //默认的列表样式
      focusClass: "mailListFocus", //列表选样式中
      markCalss: "mailListHlignt", //高亮样式
      zIndex: 1,
      autoClass: true, //是否使用插件自带class样式
      mailArr: ["qq.com","gmail.com","126.com","163.com","hotmail.com","yahoo.com","yahoo.com.cn","live.com","sohu.com","sina.com"], //邮件数组
      textHint: false, //文字提示的自动显示与隐藏
      hintText: "",
      focusColor: "#333",
      blurColor: "#999"
    };
    var settings = $.extend({}, defaults, options || {});
     
    //页面装载CSS样式
    if(settings.autoClass && $("#mailListAppendCss").size() === 0){
      $('<style id="mailListAppendCss" type="text/css">.mailListBox{border:1px solid #369; background:#fff; font:12px/20px Arial;}.mailListDefault{padding:0 5px;cursor:pointer;white-space:nowrap;}.mailListFocus{padding:0 5px;cursor:pointer;white-space:nowrap;background:#369;color:white;}.mailListHlignt{color:red;}.mailListFocus .mailListHlignt{color:#fff;}</style>').appendTo($("head")); 
    }
    var cb = settings.boxClass, cl = settings.listClass, cf = settings.focusClass, cm = settings.markCalss; //插件的class变量
    var z = settings.zIndex, newArr = mailArr = settings.mailArr, hint = settings.textHint, text = settings.hintText, fc = settings.focusColor, bc = settings.blurColor;
    //创建邮件内部列表内容
    $.createHtml = function(str, arr, cur){
      var mailHtml = "";
      if($.isArray(arr)){
        $.each(arr, function(i, n){
          if(i === cur){
            mailHtml += '<div class="mailHover '+cf+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';  
          }else{
            mailHtml += '<div class="mailHover '+cl+'" id="mailList_'+i+'"><span class="'+cm+'">'+str+'</span>@'+arr[i]+'</div>';  
          }
        });
      }
      return mailHtml;
    };
    //一些全局变量
    var index = -1, s;
    $(this).each(function(){
      var that = $(this), i = $(".justForJs").size(); 
      if(i > 0){ //只绑定一个文本框
        return; 
      }
      var w = that.outerWidth(), h = that.outerHeight(); //获取当前对象(即文本框)的宽高
      //样式的初始化
      that.wrap('<span style="display:inline-block;position:relative;"></span>')
        .before('<div id="mailListBox_'+i+'" class="justForJs '+cb+'" style="min-width:'+w+'px;_width:'+w+'px;position:absolute;left:-6000px;top:'+h+'px;z-index:'+z+';"></div>');
      var x = $("#mailListBox_" + i), liveValue; //列表框对象
      that.focus(function(){
        //父标签的层级
        $(this).css("color", fc).parent().css("z-index", z);  
        //提示文字的显示与隐藏
        if(hint && text){
          var focus_v = $.trim($(this).val());
          if(focus_v === text){
            $(this).val("");
          }
        }
        //键盘事件
        $(this).keyup(function(e){
          s = v = $.trim($(this).val()); 
          if(/@/.test(v)){
            s = v.replace(/@.*/, "");
          }
          if(v.length > 0){
            //如果按键是上下键
            if(e.keyCode === 38){
              //向上
              if(index <= 0){
                index = newArr.length; 
              }
              index--;
            }else if(e.keyCode === 40){
              //向下
              if(index >= newArr.length - 1){
                index = -1;
              }
              index++;
            }else if(e.keyCode === 13){
              //回车
              if(index > -1 && index < newArr.length){
                //如果当前有激活列表
                $(this).val($("#mailList_"+index).text()); 
              }
            }else{
              if(/@/.test(v)){
                index = -1;
                //获得@后面的值
                //s = v.replace(/@.*/, "");
                //创建新匹配数组
                var site = v.replace(/.*@/, "");
                newArr = $.map(mailArr, function(n){
                  var reg = new RegExp(site); 
                  if(reg.test(n)){
                    return n;  
                  }
                });
              }else{
                newArr = mailArr;
              }
            }
            x.html($.createHtml(s, newArr, index)).css("left", 0);
            if(e.keyCode === 13){
              //回车
              if(index > -1 && index < newArr.length){
                //如果当前有激活列表
                x.css("left", "-6000px");  
              }
            }
          }else{
            x.css("left", "-6000px");  
          }
        }).blur(function(){
          if(hint && text){
            var blur_v = $.trim($(this).val());
            if(blur_v === ""){
              $(this).val(text);
            }
          }
          $(this).css("color", bc).unbind("keyup").parent().css("z-index",0);
          x.css("left", "-6000px");  
           
        }); 
        //鼠标经过列表项事件
        //鼠标经过
        $(".mailHover").live("mouseover", function(){
          index = Number($(this).attr("id").split("_")[1]);  
          liveValue = $("#mailList_"+index).text();
          x.children("." + cf).removeClass(cf).addClass(cl);
          $(this).addClass(cf).removeClass(cl);
        });
      });
 
      x.bind("mousedown", function(){
        that.val(liveValue);    
      });
    });
  };
   
})(jQuery);
Javascript 相关文章推荐
33个优秀的jQuery 教程分享(幻灯片、动画菜单)
Jul 08 Javascript
myEvent.js javascript跨浏览器事件框架
Oct 24 Javascript
javascript模拟select,jselect的方法实现
Nov 08 Javascript
简单谈谈json跨域
Mar 13 Javascript
轻松掌握JavaScript代理模式
Aug 26 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
Mar 08 Javascript
javascript 中Cookie读、写与删除操作
Mar 29 Javascript
微信小程序开发中的疑问解答汇总
Jul 03 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
Apr 12 Javascript
node.js express框架简介与实现
Jul 23 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
Feb 07 Javascript
2020京东618叠蛋糕js脚本(亲测好用)
Jun 02 Javascript
使用 JavaScript 进行函数式编程 (一) 翻译
Oct 02 #Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
Oct 02 #Javascript
jQuery网页右侧广告跟随滚动代码分享
Apr 20 #Javascript
jQuery+PHP星级评分实现方法
Oct 02 #Javascript
谈谈JSON对象和字符串之间的相互转换JSON.stringify(obj)和JSON.parse(string)
Oct 01 #Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
Oct 01 #Javascript
基于OL2实现百度地图ABCD marker的效果
Oct 01 #Javascript
You might like
php统计文章排行示例
2014/03/04 PHP
Smarty foreach控制循环次数的一些方法
2015/07/01 PHP
php中session定期自动清理的方法
2015/11/12 PHP
JQuery的html(data)方法与&amp;lt;script&amp;gt;脚本块的解决方法
2010/03/09 Javascript
Extjs在exlipse中设置自动提示的方法
2010/04/07 Javascript
写得不错的jquery table鼠标经过变色代码
2013/09/27 Javascript
悬浮数字的实现案例
2014/02/19 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
js计算任意值之间随机数的方法
2015/01/16 Javascript
AspNet中使用JQuery boxy插件的确认框
2015/05/20 Javascript
javascript中setInterval的用法
2015/07/19 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
微信通过页面(H5)直接打开本地app的解决方法
2017/09/09 Javascript
解决Vue不能检测数组或对象变动的问题
2018/02/24 Javascript
vue如何引入sass全局变量
2018/06/28 Javascript
Vue框架里使用Swiper的方法示例
2018/09/20 Javascript
vue中监听返回键问题
2019/08/28 Javascript
Node.js 实现抢票小工具 &amp; 短信通知提醒功能
2019/10/22 Javascript
python基于xml parse实现解析cdatasection数据
2014/09/30 Python
利用python求解物理学中的双弹簧质能系统详解
2017/09/29 Python
Python IDLE入门简介
2017/12/08 Python
python中使用%与.format格式化文本方法解析
2017/12/27 Python
解决python使用open打开文件中文乱码的问题
2017/12/29 Python
python实现对输入的密文加密
2019/03/20 Python
PyCharm 在Windows的有用快捷键详解
2020/04/07 Python
Django 允许局域网中的机器访问你的主机操作
2020/05/13 Python
Python爬取YY评级分数并保存数据实现过程解析
2020/06/01 Python
python:HDF和CSV存储优劣对比分析
2020/06/08 Python
给领导的致歉信范文
2014/01/13 职场文书
高一地理教学反思
2014/01/18 职场文书
单位一把手群众路线四风问题整改措施
2014/09/25 职场文书
行政诉讼答辩状
2015/05/21 职场文书
2016年教育局“我们的节日——端午节”主题活动总结
2016/04/01 职场文书
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
2021/10/16 Python
Java8 Stream API 提供了一种高效且易于使用的处理数据的方式
2022/04/13 Java/Android
Golang入门之计时器
2022/05/04 Golang