微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

jQuery 实现自动填充邮箱功能带下拉提示

在做这个功能时候,我参考的是网易注册(http://reg.163.com/reg/reg.jsp?product=urs)中的邮箱栏目所实现的功能效果。这个功能的目的是使用户在填写邮箱栏目的过程中,在带有邮箱后缀名的菜单提示下,可以不需要完整输入自己的注册邮箱,达到方便、快捷、友好的效果。在做这个功能的时候,需要充分站在使用者的角度,看怎样设计能够最符合通常情况下人们的使用习惯,又怎样设计反而会让用户感到不便。先来看看功能实现的演示效果图:

在线演示:http://jsfiddle.net/vudr00xc/embedded/result/

①初始状态,邮箱栏目未获得焦点时

以及鼠标点击后获得焦点时

②以空白字符( space,tab ) 以及@开头时,不出现提示菜单

③输入有效字符时,提示下拉菜单出现,用户输入的内容自动添加菜单,并且第一条提示栏目获得高亮

④输入的字符第一次出现"@"时,输入的"@"并不加入提示菜单

⑤"@"之后出现有效字符时,就会同提示菜单中的邮件后缀从后缀首位起进行比较,把和用户输入的邮箱后缀不同的提示菜单中去掉。同时过滤后的第一条提示获得高亮。在完全匹配之后,下拉菜单隐藏。

用户删除邮件输入框中的字符时,呈现的效果顺序是⑤图3--->⑤图2---> ⑤图1---> ④图

⑦按下键盘方向键向上或向下使菜单相应提示高亮

⑧鼠标划过菜单提示时,原先的高亮消失,鼠标划过的栏目获得高亮;鼠标移开,保持之前鼠标划过的栏目高亮,直到用户继续输入字符,栏目失去高亮,同时第一条可见的提示高亮

⑨点击高亮提示或者高亮处回车,自动填充邮箱元素,选择完成,菜单收起

⑩在下拉菜单展开时,鼠标点击页面任何元素,菜单收起

注:此功能包括正则验证邮箱格式。

功能没有用到什么复杂的知识点,只有简单的JS字符串的匹配 ( match )、位置检索 ( indexOf ) 、截取 ( substr ) 以及jQuery选择器的应用等。更主要的是对功能的逻辑分析要思路清晰,以及思考如何设计能真正使用户操作简便。这个功能的事件主要包括

代码分析:

HTML和CSS代码

HTML

rush:xhtml;">

CSS

rush:css;"> .ipt{ width:218px;}/* 输入框外围div */ input{ margin:0; padding-left:15px; padding-right:15px; width:184px;}/* 输入框 */ ul.autoul{ /* 下拉菜单 */

width:216px;
margin:0px;
margin-top:-5px;
padding:0px;
color:#666;
border:1px solid #666;
border-top:0;
overflow:hidden;
}
ul.autoul li.autoli{ / 下拉菜单li /

height:30px;
display:block;
list-style-type:none;
text-align:left;
cursor:pointer;
font-size:14px;
line-height:30px;
padding-left:15px;
padding-right:15px;
overflow:hidden;
/当对象内文本溢出时显示省略标记/
text-overflow:ellipsis;
}
.lihover{ / 下拉菜单li高亮样式 /

background-color:#eee;
}
span{ padding-right:2px;}/ li下文字 /
.showli{ display:block;}/ 经过过滤的li的样式 /

在DOM加载完毕后,初始化邮件列表并隐藏下拉菜单,JS代码片段:

rush:js;"> $(function(){

//初始化邮箱列表
var mail = new Array("sina.com","126.com","163.com","gmail.com","qq.com","vip.qq.com","hotmail.com","sohu.com","139.com","vip.sina.com","21cn.cn","189.cn","sina.cn");

//把邮箱列表加入下拉
for(var i=0;i<mail.length;i++){

var $liElement = $("<li class=\"autoli\"&gt;<span class=\"ex\"&gt;</span><span class=\"at\"&gt;@</span><span class=\"step\"&gt;"+mail[i]+"</span></li>");

$liElement.appendTo("ul.autoul");

}

//下拉菜单初始隐藏
$(".autoul").hide();

//其他事件..........
});

输入框$("#uemail")的keyup和keydown事件是该功能的主要事件,输入字符时之所以用keyup事件而不用keydown事件是因为keyup事件在用户键盘按键抬起时触发,是整个按键动作的最后阶段,所以在抬起按键时能看到相应的动作即实时看到输入的字符;而使用keydown事件时,只有在下一次按下键盘按键时才能看到上一次按下按键触发的动作,所以keydown事件在通过键盘获得页面控制方面用的比较多,因此在使用键盘方向键↑↓选择菜单提示时使用keydown事件。

rush:js;"> //在邮箱输入框输入字符 $("#uemail").keyup(function(){
//........

})

邮件输入框$("#uemail")的keyup事件:

①有输入的按键,使输入框有长度( 因为删除事件也是判断匹配以及长度,所以只需要添加删除事件特有的动作,而不必在此处排除删除事件 )

//菜单展现,需要排除空格开头和"@"开头 if( $.trim($(this).val())!="" && $.trim(this.value).match(/^@/)==null ) { $(".autoul").show(); //同时去掉原先的高亮,把第一条提示高亮 if($(".autoul li.lihover").hasClass("lihover")) { $(".autoul li.lihover").removeClass("lihover"); } $(".autoul li:visible:eq(0)").addClass("lihover"); }else{//如果为空或者"@"开头 $(".autoul").hide(); $(".autoul li:eq(0)").removeClass("lihover"); } //把输入的字符填充进提示,有两种情况:1.出现"@"之前,把"@"之前的字符进行填充;2.出现第一次"@"时以及"@"之后还有字符时,不填充 //出现@之前 if($.trim(this.value).match(/[^@]@/)==null){//输入了不含"@"的字符或者"@"开头 if($.trim(this.value).match(/^@/)==null){ //不以"@"开头 $(this).next().children("li").children(".ex").text($(this).val()); } }else{ //输入字符后,第一次出现了不在首位的"@" //当首次出现@之后,有2种情况:1.继续输入;2.没有继续输入 //当继续输入时 var str = this.value;//输入的所有字符 var strs = new Array(); strs = str.split("@");//输入的所有字符以"@"分隔 $(".ex").text(strs[0]);//"@"之前输入的内容 var len = strs[0].length;//"@"之前输入内容的长度 if(this.value.length>len+1){ //<a href="https://www.jb51.cc/tag/jiequ/" target="_blank" class="keywords">截取</a>出@之后的字符串,@之前字符串的长度加@的长度,从第(len+1)位开始<a href="https://www.jb51.cc/tag/jiequ/" target="_blank" class="keywords">截取</a> var strright = str.substr(len+1); //正则<a href="https://www.jb51.cc/tag/pingbi/" target="_blank" class="keywords">屏蔽</a>匹配反斜杠"\" if(strright.match(/[\\]/)!=null){ strright.replace(/[\\]/,""); return false; } //遍历li $("ul.autoul li").each(function(){ //遍历span //$(this) li $(this).children("span.step").each(function(){ //@之后的字符串与<a href="https://www.jb51.cc/tag/youjian/" target="_blank" class="keywords">邮件</a>后缀进行比较 //当输入的字符和下拉中<a href="https://www.jb51.cc/tag/youjian/" target="_blank" class="keywords">邮件</a>后缀匹配并且出现在第一位出现 //$(this) span.step if($("ul.autoul li").children("span.step").text().match(strright)!=null && $(this).text().indexOf(strright)==0){ //class showli是输入框@后的字符和<a href="https://www.jb51.cc/tag/youjian/" target="_blank" class="keywords">邮件</a>列表对比匹配后给匹配的<a href="https://www.jb51.cc/tag/youjian/" target="_blank" class="keywords">邮件</a>li<a href="https://www.jb51.cc/tag/jiashang/" target="_blank" class="keywords">加上</a>的<a href="https://www.jb51.cc/tag/shuxing/" target="_blank" class="keywords">属性</a> $(this).parent().addClass("showli"); //如果输入的字符和<a href="https://www.jb51.cc/tag/tishi/" target="_blank" class="keywords">提示</a><a href="https://www.jb51.cc/tag/caidan/" target="_blank" class="keywords">菜单</a>完全匹配,则去掉高亮和showli,同时<a href="https://www.jb51.cc/tag/tishi/" target="_blank" class="keywords">提示</a>隐藏 if(strright.length>=$(this).text().length){ $(this).parent().removeClass("showli").removeClass("lihover").hide(); } }else{ $(this).parent().removeClass("showli"); } if($(this).parent().hasClass("showli")){ $(this).parent().show(); $(this).parent("li").parent("ul").children("li.showli:eq(0)").addClass("lihover"); }else{ $(this).parent().hide(); $(this).parent().removeClass("lihover"); } }); }); }else{ //"@"后没有继续输入时 $(".autoul").children().show(); $("ul.autoul li").removeClass("showli"); $("ul.autoul li.lihover").removeClass("lihover"); $("ul.autoul li:eq(0)").addClass("lihover"); } }

}//有效输入按键事件结束

②按键为backspace(8)或是delete(46)

rush:xhtml;"> if(event.keyCode == 8 || event.keyCode == 46){

$(this).next().children().removeClass("lihover");
$(this).next().children("li:visible:eq(0)").addClass("lihover");
}//删除事件结束

③按键为方向键↑(38)

rush:js;"> if(event.keyCode == 38){ //使光标始终在输入框文字右边 $(this).val($(this).val()); }//方向键↑结束

④按键为回车键(13)

rush:js;"> if(event.keyCode == 13){
  if($("ul.autoul li").is(".lihover")) {

    $("#uemail").val($("ul.autoul li.lihover").children(".ex").text() + "@" + $("ul.autoul li.lihover").children(".step").text());
  }

  $(".autoul").children().hide();
  $(".autoul").children().removeClass("lihover"); 
  $("#uemail").focus();//回车后输入栏获得焦点

}

至此keyup事件结束。

#("#uemail")的keydown事件

rush:js;"> $("#uemail").keydown(function(){

if(event.keyCode == 40){
//按键为↓时....
}

if(event.keyCode == 38){
//按键为↑时....
}
})

⑤按键为方向键 ↓ (40)

rush:js;"> if(event.keyCode == 40){
  //当<a href="https://www.jb51.cc/tag/jianpan/" target="_blank" class="keywords">键盘</a>按下↓时,如果已经有li处于被选中的状态,则去掉状态,并把样式赋给下一条(可见的)li
  if ($("ul.autoul li").is(".lihover")) {

    //如果还存在下一条(可见的)li的话
    if ($("ul.autoul li.lihover").nextAll().is("li:visible")) {

      if ($("ul.autoul li.lihover").nextAll().hasClass("showli")) {

        $("ul.autoul li.lihover").removeClass("lihover")
            .nextAll(".showli:eq(0)").addClass("lihover");
      } else {

        $("ul.autoul li.lihover").removeClass("lihover").removeClass("showli")
            .next("li:visible").addClass("lihover");
        $("ul.autoul").children().show();
      }
    } else {

      $("ul.autoul li.lihover").removeClass("lihover");
      $("ul.autoul li:visible:eq(0)").addClass("lihover");
    }
  } 

}

⑥按键为方向键 ↑ (38)

rush:js;"> if(event.keyCode == 38){
  //当<a href="https://www.jb51.cc/tag/jianpan/" target="_blank" class="keywords">键盘</a>按下↓时,并把样式赋给下一条(可见的)li
  if($("ul.autoul li").is(".lihover")){

    //如果还存在上一条(可见的)li的话
    if($("ul.autoul li.lihover").prevAll().is("li:visible")){


      if($("ul.autoul li.lihover").prevAll().hasClass("showli")){

        $("ul.autoul li.lihover").removeClass("lihover")
            .prevAll(".showli:eq(0)").addClass("lihover");
      }else{

        $("ul.autoul li.lihover").removeClass("lihover").removeClass("showli")
            .prev("li:visible").addClass("lihover");
        $("ul.autoul").children().show();
      }
    }else{

      $("ul.autoul li.lihover").removeClass("lihover");
      $("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
    }
  }else{

    //当<a href="https://www.jb51.cc/tag/jianpan/" target="_blank" class="keywords">键盘</a>按下↓时,如果之前没有一条li被选中的话,则第一条(可见的)li被选中
    $("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
  }

}

至此keydown事件结束。

⑦当鼠标点击下拉菜单的具体一条内容

rush:js;"> $(".autoli").click(function(){
 $("#uemail").val($(this).children(".ex").text()+$(this).children(".at").text()+$(this).children(".step").text());
 $(".autoul").hide();

});
//鼠标点击下拉菜单具体内容事件结束

⑧当鼠标点击document时,下拉隐藏

rush:js;"> $("body").click(function(){
 $(".autoul").hide();

});
//鼠标点击document事件结束

⑨鼠标划过li时

rush:js;"> $("ul.autoul li").hover(function(){
if($("ul.autoul li").hasClass("lihover")){

  $("ul.autoul li").removeClass("lihover");
}
$(this).addClass("lihover");

});

至此,功能完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐