jQuery 實(shí)現(xiàn)自動(dòng)填充郵箱功能(帶下拉提示)
在做這個(gè)功能時(shí)候,我參考的是網(wǎng)易注冊(cè)(http://reg.163.com/reg/reg.jsp?product=urs)中的郵箱欄目所實(shí)現(xiàn)的功能與效果。這個(gè)功能的目的是使用戶在填寫郵箱欄目的過程中,在帶有郵箱后綴名的菜單的提示下,可以不需要完整輸入自己的注冊(cè)郵箱,達(dá)到方便、快捷、友好的效果。在做這個(gè)功能的時(shí)候,需要充分站在使用者的角度,看怎樣設(shè)計(jì)能夠最符合通常情況下人們的使用習(xí)慣,又怎樣設(shè)計(jì)反而會(huì)讓用戶感到不便。先來看看功能實(shí)現(xiàn)的演示效果圖:
在線演示:http://jsfiddle.net/vudr00xc/embedded/result/
①初始狀態(tài),郵箱欄目未獲得焦點(diǎn)時(shí)

以及鼠標(biāo)點(diǎn)擊后獲得焦點(diǎn)時(shí)

②以空白字符( space , tab ) 以及@開頭時(shí),不出現(xiàn)提示菜單

③輸入有效字符時(shí),提示下拉菜單出現(xiàn),用戶輸入的內(nèi)容自動(dòng)添加進(jìn)菜單,并且第一條提示欄目獲得高亮

④輸入的字符第一次出現(xiàn)"@"時(shí),輸入的"@"并不加入提示菜單

⑤"@"之后出現(xiàn)有效字符時(shí),就會(huì)同提示菜單中的郵件后綴從后綴首位起進(jìn)行比較,把和用戶輸入的郵箱后綴不同的提示從菜單中去掉。同時(shí)過濾后的第一條提示獲得高亮。在完全匹配之后,下拉菜單隱藏。



⑥用戶刪除郵件輸入框中的字符時(shí),呈現(xiàn)的效果順序是⑤圖3--->⑤圖2---> ⑤圖1---> ④圖
⑦按下鍵盤方向鍵向上或向下使菜單相應(yīng)提示高亮

⑧鼠標(biāo)劃過菜單提示時(shí),原先的高亮消失,鼠標(biāo)劃過的欄目獲得高亮;鼠標(biāo)移開,保持之前鼠標(biāo)劃過的欄目高亮,直到用戶繼續(xù)輸入字符,欄目失去高亮,同時(shí)第一條可見的提示高亮

⑨點(diǎn)擊高亮提示或者高亮處回車,自動(dòng)填充郵箱元素,選擇完成,菜單收起

⑩在下拉菜單展開時(shí),鼠標(biāo)點(diǎn)擊頁面任何元素,菜單收起
注:此功能不包括正則驗(yàn)證郵箱格式。
本功能沒有用到什么復(fù)雜的知識(shí)點(diǎn),只有簡單的JS字符串的匹配 ( match )、位置檢索 ( indexOf ) 、截取 ( substr ) 以及jQuery選擇器的應(yīng)用等。更主要的是對(duì)功能的邏輯分析要思路清晰,以及思考如何設(shè)計(jì)能真正使用戶操作簡便。這個(gè)功能的事件主要包括:

代碼分析:
HTML和CSS代碼:
HTML
<div class="ipt"> <input type="text" name="uemail" id="uemail" placeholder="請(qǐng)輸入常用郵箱"/> <ul class="autoul"></ul> </div>
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;
/*當(dāng)對(duì)象內(nèi)文本溢出時(shí)顯示省略標(biāo)記*/
text-overflow:ellipsis;
}
.lihover{ /* 下拉菜單li高亮樣式 */
background-color:#eee;
}
span{ padding-right:2px;}/* li下文字 */
.showli{ display:block;}/* 經(jīng)過過濾的li的樣式 */
在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事件是該功能的主要事件,輸入字符時(shí)之所以用keyup事件而不用keydown事件是因?yàn)閗eyup事件在用戶將鍵盤按鍵抬起時(shí)觸發(fā),是整個(gè)按鍵動(dòng)作的最后階段,所以在抬起按鍵時(shí)能看到相應(yīng)的動(dòng)作即實(shí)時(shí)看到輸入的字符;而使用keydown事件時(shí),只有在下一次按下鍵盤按鍵時(shí)才能看到上一次按下按鍵觸發(fā)的動(dòng)作,所以keydown事件在通過鍵盤獲得頁面控制方面用的比較多,因此在使用鍵盤方向鍵↑↓選擇菜單提示時(shí)使用keydown事件。
//在郵箱輸入框輸入字符
$("#uemail").keyup(function(){
//........
})
郵件輸入框$("#uemail")的keyup事件:
①有輸入的按鍵,使輸入框有長度( 因?yàn)閯h除事件也是判斷匹配以及長度,所以只需要添加刪除事件特有的動(dòng)作,而不必在此處排除刪除事件 )
if(event.keyCode!=38 && event.keyCode!=40 && event.keyCode!=13){
//菜單展現(xiàn),需要排除空格開頭和"@"開頭
if( $.trim($(this).val())!="" && $.trim(this.value).match(/^@/)==null ) {
$(".autoul").show();
//同時(shí)去掉原先的高亮,把第一條提示高亮
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");
}
//把輸入的字符填充進(jìn)提示,有兩種情況:1.出現(xiàn)"@"之前,把"@"之前的字符進(jìn)行填充;2.出現(xiàn)第一次"@"時(shí)以及"@"之后還有字符時(shí),不填充
//出現(xiàn)@之前
if($.trim(this.value).match(/[^@]@/)==null){//輸入了不含"@"的字符或者"@"開頭
if($.trim(this.value).match(/^@/)==null){
//不以"@"開頭
$(this).next().children("li").children(".ex").text($(this).val());
}
}else{
//輸入字符后,第一次出現(xiàn)了不在首位的"@"
//當(dāng)首次出現(xiàn)@之后,有2種情況:1.繼續(xù)輸入;2.沒有繼續(xù)輸入
//當(dāng)繼續(xù)輸入時(shí)
var str = this.value;//輸入的所有字符
var strs = new Array();
strs = str.split("@");//輸入的所有字符以"@"分隔
$(".ex").text(strs[0]);//"@"之前輸入的內(nèi)容
var len = strs[0].length;//"@"之前輸入內(nèi)容的長度
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(){
//@之后的字符串與郵件后綴進(jìn)行比較
//當(dāng)輸入的字符和下拉中郵件后綴匹配并且出現(xiàn)在第一位出現(xiàn)
//$(this) span.step
if($("ul.autoul li").children("span.step").text().match(strright)!=null && $(this).text().indexOf(strright)==0){
//class showli是輸入框@后的字符和郵件列表對(duì)比匹配后給匹配的郵件li加上的屬性
$(this).parent().addClass("showli");
//如果輸入的字符和提示菜單完全匹配,則去掉高亮和showli,同時(shí)提示隱藏
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{
//"@"后沒有繼續(xù)輸入時(shí)
$(".autoul").children().show();
$("ul.autoul li").removeClass("showli");
$("ul.autoul li.lihover").removeClass("lihover");
$("ul.autoul li:eq(0)").addClass("lihover");
}
}
}//有效輸入按鍵事件結(jié)束
②按鍵為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");
}//刪除事件結(jié)束
③按鍵為方向鍵↑(38)
if(event.keyCode == 38){
//使光標(biāo)始終在輸入框文字右邊
$(this).val($(this).val());
}//方向鍵↑結(jié)束
④按鍵為回車鍵(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");
$("#uemail").focus();//回車后輸入欄獲得焦點(diǎn)
}
至此keyup事件結(jié)束。
#("#uemail")的keydown事件
$("#uemail").keydown(function(){
if(event.keyCode == 40){
//按鍵為↓時(shí)....
}
if(event.keyCode == 38){
//按鍵為↑時(shí)....
}
})
⑤按鍵為方向鍵 ↓ (40)
if(event.keyCode == 40){
//當(dāng)鍵盤按下↓時(shí),如果已經(jīng)有l(wèi)i處于被選中的狀態(tài),則去掉狀態(tài),并把樣式賦給下一條(可見的)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){
//當(dāng)鍵盤按下↓時(shí),如果已經(jīng)有l(wèi)i處于被選中的狀態(tài),則去掉狀態(tài),并把樣式賦給下一條(可見的)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{
//當(dāng)鍵盤按下↓時(shí),如果之前沒有一條li被選中的話,則第一條(可見的)li被選中
$("ul.autoul li:visible:eq("+($("ul.autoul li:visible").length-1)+")").addClass("lihover");
}
}
至此keydown事件結(jié)束。
⑦當(dāng)鼠標(biāo)點(diǎn)擊下拉菜單的具體一條內(nèi)容時(shí)
$(".autoli").click(function(){
$("#uemail").val($(this).children(".ex").text()+$(this).children(".at").text()+$(this).children(".step").text());
$(".autoul").hide();
});
//鼠標(biāo)點(diǎn)擊下拉菜單具體內(nèi)容事件結(jié)束
⑧當(dāng)鼠標(biāo)點(diǎn)擊document時(shí),下拉隱藏
$("body").click(function(){
$(".autoul").hide();
});
//鼠標(biāo)點(diǎn)擊document事件結(jié)束
⑨鼠標(biāo)劃過li時(shí)
$("ul.autoul li").hover(function(){
if($("ul.autoul li").hasClass("lihover")){
$("ul.autoul li").removeClass("lihover");
}
$(this).addClass("lihover");
});
至此,功能完成。
相關(guān)文章
jQuery漸變發(fā)光導(dǎo)航菜單的實(shí)例代碼
今天介紹一個(gè)jQuery漸變發(fā)光效果的導(dǎo)航菜單,這是一個(gè)簡單的通過jQuery控制opacity實(shí)現(xiàn)的導(dǎo)航菜單。2013-03-03
jquery實(shí)現(xiàn)的3D旋轉(zhuǎn)木馬特效代碼分享
這篇文章主要介紹了jquery實(shí)現(xiàn)的3D旋轉(zhuǎn)木馬特效,功能實(shí)現(xiàn)非常簡單,推薦給大家,有需要的小伙伴可以參考下。2015-08-08
jQuery實(shí)現(xiàn)的簡單日歷組件定義與用法示例
這篇文章主要介紹了jQuery實(shí)現(xiàn)的簡單日歷組件定義與用法,結(jié)合實(shí)例形式詳細(xì)分析了基于jQuery擴(kuò)展實(shí)現(xiàn)日歷功能的相關(guān)操作技巧,需要的朋友可以參考下2018-12-12
基于jQuery實(shí)現(xiàn)響應(yīng)式圓形圖片輪播特效
這篇文章主要介紹了基于jQuery實(shí)現(xiàn)響應(yīng)式圓形圖片輪播特效,mislider插件可以將圖片以圓形圖片顯示,然后使圖片無限循環(huán)形成輪播圖或旋轉(zhuǎn)木馬特效,感興趣的小伙伴們可以參考一下2015-11-11
jQuery刪除一個(gè)元素后淡出效果展示刪除過程的方法
這篇文章主要介紹了jQuery刪除一個(gè)元素后淡出效果展示刪除過程的方法,實(shí)例分析了jQuery中fadeTo及slideUp等方法的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-03-03
基于jQuery模擬實(shí)現(xiàn)淘寶購物車模塊
這篇文章主要介紹了如何利用jQuery+css+html模擬實(shí)現(xiàn)淘寶購物車模塊,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起動(dòng)手嘗試一下2022-03-03

