jQuery 实现带下拉提示且自动填充的邮箱
/*
** 本文例子所引用的jQuery版本为 jQuery-1.8.3.min.js
** Author:博客园小dee
*/
本文用 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代码:
<div class="ipt">
<input type="text" name="uemail" id="uemail" placeholder="请输入常用邮箱"/>
<ul class="autoul"></ul>
</div>
HTML
.ipt{ width:218px;}/* 输入框外围div */
input{ margin:; 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:;
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的样式 */
CSS
在DOM加载完毕后,初始化邮件列表并隐藏下拉菜单,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\"><span class=\"ex\"></span><span class=\"at\">@</span><span class=\"step\">"+mail[i]+"</span></li>");
$liElement.appendTo("ul.autoul");
}
//下拉菜单初始隐藏
$(".autoul").hide();
//其他事件..........
});
输入框$("#uemail")的keyup和keydown事件是该功能的主要事件,输入字符时之所以用keyup事件而不用keydown事件是因为keyup事件在用户将键盘按键抬起时触发,是整个按键动作的最后阶段,所以在抬起按键时能看到相应的动作即实时看到输入的字符;而使用keydown事件时,只有在下一次按下键盘按键时才能看到上一次按下按键触发的动作,所以keydown事件在通过键盘获得页面控制方面用的比较多,因此在使用键盘方向键↑↓选择菜单提示时使用keydown事件。
//在邮箱输入框输入字符
$("#uemail").keyup(function(){ //........
})
邮件输入框$("#uemail")的keyup事件:
①有输入的按键,使输入框有长度( 因为删除事件也是判断匹配以及长度,所以只需要添加删除事件特有的动作,而不必在此处排除删除事件 )
if(event.keyCode!=38 && event.keyCode!=40 && event.keyCode!=13){
//菜单展现,需要排除空格开头和"@"开头
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){
//截取出@之后的字符串,@之前字符串的长度加@的长度,从第(len+1)位开始截取
var strright = str.substr(len+1);
//正则屏蔽匹配反斜杠"\"
if(strright.match(/[\\]/)!=null){
strright.replace(/[\\]/,"");
return false;
}
//遍历li
$("ul.autoul li").each(function(){
//遍历span
//$(this) li
$(this).children("span.step").each(function(){
//@之后的字符串与邮件后缀进行比较
//当输入的字符和下拉中邮件后缀匹配并且出现在第一位出现
//$(this) span.step
if($("ul.autoul li").children("span.step").text().match(strright)!=null && $(this).text().indexOf(strright)==0){
//class showli是输入框@后的字符和邮件列表对比匹配后给匹配的邮件li加上的属性
$(this).parent().addClass("showli");
//如果输入的字符和提示菜单完全匹配,则去掉高亮和showli,同时提示隐藏
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)
if(event.keyCode == 8 || event.keyCode == 46){
$(this).next().children().removeClass("lihover");
$(this).next().children("li:visible:eq(0)").addClass("lihover");
}//删除事件结束
③按键为方向键↑(38)
if(event.keyCode == 38){
//使光标始终在输入框文字右边
$(this).val($(this).val());
}//方向键↑结束
④按键为回车键(13)
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");
10 $("#uemail").focus();//回车后输入栏获得焦点
}
至此keyup事件结束。
#("#uemail")的keydown事件
$("#uemail").keydown(function(){
if(event.keyCode == 40){
//按键为↓时....
}
if(event.keyCode == 38){
//按键为↑时....
}
})
⑤按键为方向键 ↓ (40)
if(event.keyCode == 40){
//当键盘按下↓时,如果已经有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)
if(event.keyCode == 38){
//当键盘按下↓时,如果已经有li处于被选中的状态,则去掉状态,并把样式赋给下一条(可见的)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{
//当键盘按下↓时,如果之前没有一条li被选中的话,则第一条(可见的)li被选中
$("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
}
}
至此keydown事件结束。
⑦当鼠标点击下拉菜单的具体一条内容时
$(".autoli").click(function(){
$("#uemail").val($(this).children(".ex").text()+$(this).children(".at").text()+$(this).children(".step").text());
$(".autoul").hide();
});
//鼠标点击下拉菜单具体内容事件结束
⑧当鼠标点击document时,下拉隐藏
$("body").click(function(){
$(".autoul").hide();
});
//鼠标点击document事件结束
⑨鼠标划过li时
$("ul.autoul li").hover(function(){
if($("ul.autoul li").hasClass("lihover")){
$("ul.autoul li").removeClass("lihover");
}
$(this).addClass("lihover");
});
至此,功能完成。
如需转载,请在文章页面保留此说明并且给出原文链接。谢谢!
jQuery 实现带下拉提示且自动填充的邮箱的更多相关文章
- 基于jQuery的input输入框下拉提示层(自动邮箱后缀名)
基于jQuery的input输入框下拉提示层,方便用户输入邮箱时的提示信息,需要的朋友可以参考下 效果图 // JavaScript Document (function($){ $.fn ...
- Excel2013下拉框选择自动填充颜色
图一写判断公式,图二选择应用范围.
- jquery带下拉菜单和焦点图
jQuery,下拉菜单,二级菜单,索引按钮,焦点图代码,jquery带下拉菜单和焦点图是一款顶部通栏带二级下拉菜单和banner导航菜单代码. JQuery特效代码来源:http://www.huiy ...
- 基于jQuery美化联动下拉选择框
今天给大家介绍一款基于jQuery美化联动下拉选择框.这款下下拉选择框js里自带了全国所有城市的数数库.下拉选择框适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲 ...
- jquery实现多级下拉菜单
支持多种浏览器,体验效果:http://keleyi.com/keleyi/phtml/jqmenu/4.htm 多级菜单,理论上支持无限多的层级,文件结构非常简单的,以下是完整代码: <!DO ...
- jQuery超酷下拉插件6种效果演示
原始的下拉框很丑啦, 给大家一款jQuery超酷下拉插件6种效果 效果预览 下载地址 实例代码 <div class="container"> <section ...
- Bootstrap页面布局15 - BS带下拉菜单的按钮
带下拉菜单的按钮 <div class='btn-toolbar'> <div class='btn-group'> <a href='javascript:;' cla ...
- 一款jQuery立体感动态下拉导航菜单特效
一款jQuery立体感动态下拉导航菜单特效,鼠标经过,在菜单栏上方下拉出一个背景图片,效果十分不错的一款jquery特效. 对IE6都是兼容的,希望大家好好研究研究. 适用浏览器:IE6.IE7.IE ...
- 一款jquery编写图文下拉二级导航菜单特效
一款jquery编写图文下拉二级导航菜单特效,效果非常简洁大气,很不错的一款jquery导航菜单特效. 这款jquery特效适用于很多的个人和门户网站. 适用浏览器:IE8.360.FireFox.C ...
随机推荐
- linux安装gcc
方法:输入命令: :(1) :yum -y install gcc (2) yum -y install gcc-c++(3)yum install make 我的再输入 yum -y instal ...
- KMP模式匹配
http://www.cnblogs.com/wangguchangqing/archive/2012/09/09/2677701.html nextal[j+1]=next[j]+1 KMP算法的实 ...
- ubuntu14.04安装与配置nginx服务器
去年曾经配置过nginx服务器,可惜的是,几个月前因故障磁盘被格式化.今天又要用到nginx服务,所以从新配置了一番,但这次就不是那么顺利了.在此,愿与大家分享一下经验.只是简单的局域网应用,并未复杂 ...
- WMI
https://wiki.jenkins-ci.org/display/JENKINS/Windows+slaves+fail+to+start+via+DCOM#Windowsslavesfailt ...
- git branch -D 大写的D 删除分支
今天删除本地分支 git branch -d XXX 提示: the branch XXX is not fully merged 原因:XXX分支有没有合并到当前分支的内容 解决方法:使用大写的 ...
- C#中使用ListView动态添加数据不闪烁并显示当前插入值
首先,自定义一个类ListViewNF,继承自 System.Windows.Forms.ListView class ListViewNF : System.Windows.Forms.ListVi ...
- Hark的数据结构与算法练习之鸽巢排序
算法说明 鸽巢排序是分布排序的一种,我理解其实鸽巢就是计数排序的简化版,不同之处就是鸽巢是不稳定的,计数排序是稳定的. 逻辑很简单,就是先找出待排数组的最大值maxNum,然后实例一个maxNum+1 ...
- ThreadLocal使用和原理
实现机制 1.每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal. /* ThreadLocal values ...
- node相关--代码共享
代码共享问题: 是否值得在两个环境中运行同一份代码: //看项目 依赖的API是否在两个环境中都有或有替代: 浏览器提供的标准API:XMLHttpRequest.WebSocket.DOM.canv ...
- git将本地仓库上传到远程仓库
在已有的Git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中,从而开始一个新的项目 首先,在本地新建文件夹abc,进入到abc里面,然后git init.这样就在本地初始化了一个g ...