天天看點

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

在做這個功能時候,我參考的是網易注冊(http://reg.163.com/reg/reg.jsp?product=urs)中的郵箱欄目所實作的功能與效果。這個功能的目的是使使用者在填寫郵箱欄目的過程中,在帶有郵箱字尾名的菜單的提示下,可以不需要完整輸入自己的注冊郵箱,達到友善、快捷、友好的效果。在做這個功能的時候,需要充分站在使用者的角度,看怎樣設計能夠最符合通常情況下人們的使用習慣,又怎樣設計反而會讓使用者感到不便。先來看看功能實作的示範效果圖:

線上示範:http://jsfiddle.net/vudr00xc/embedded/result/

①初始狀态,郵箱欄目未獲得焦點時

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

以及滑鼠點選後獲得焦點時

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

②以空白字元( space , tab ) 以及@開頭時,不出現提示菜單

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

③輸入有效字元時,提示下拉菜單出現,使用者輸入的内容自動添加進菜單,并且第一條提示欄目獲得高亮

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

④輸入的字元第一次出現"@"時,輸入的"@"并不加入提示菜單

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

⑤"@"之後出現有效字元時,就會同提示菜單中的郵件字尾從字尾首位起進行比較,把和使用者輸入的郵箱字尾不同的提示從菜單中去掉。同時過濾後的第一條提示獲得高亮。在完全比對之後,下拉菜單隐藏。

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)
oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)
oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

⑥使用者删除郵件輸入框中的字元時,呈現的效果順序是⑤圖3--->⑤圖2---> ⑤圖1---> ④圖

⑦按下鍵盤方向鍵向上或向下使菜單相應提示高亮

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

⑧滑鼠劃過菜單提示時,原先的高亮消失,滑鼠劃過的欄目獲得高亮;滑鼠移開,保持之前滑鼠劃過的欄目高亮,直到使用者繼續輸入字元,欄目失去高亮,同時第一條可見的提示高亮

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

⑨點選高亮提示或者高亮處回車,自動填充郵箱元素,選擇完成,菜單收起

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

⑩在下拉菜單展開時,滑鼠點選頁面任何元素,菜單收起

注:此功能不包括正則驗證郵箱格式。

本功能沒有用到什麼複雜的知識點,隻有簡單的JS字元串的比對 ( match )、位置檢索 ( indexOf ) 、截取 ( substr ) 以及jQuery選擇器的應用等。更主要的是對功能的邏輯分析要思路清晰,以及思考如何設計能真正使使用者操作簡便。這個功能的事件主要包括:

oracle 自動填充,jQuery 實作自動填充郵箱功能(帶下拉提示)

代碼分析:

HTML和CSS代碼:

HTML

CSS

.ipt{ width:218px;}

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{

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{

background-color:#eee;

}

span{ padding-right:2px;}

.showli{ display:block;}

在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

var $liElement = $("

@ "+mail[i]+"");

$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());

}//方向鍵↑結束

④按鍵為Enter鍵(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();//回車後輸入欄獲得焦點

}

至此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");

});

至此,功能完成。