// JavaScript Document (function($){ $.fn.extend({ "changeTips":function(value){ value = $.extend({ divTip:"" },value) var $this = $(this); var indexLi = 0; //點擊document隱藏下拉層 $(document).click(function(event){ if($(event.target).attr("class") == value.divTip || $(event.target).is("li")){ var liVal = $(event.target).text(); $this.val(liVal); blus(); }else{ blus(); } }) //隱藏下拉層 function blus(){ $(value.divTip).hide(); } //鍵盤上下執行的函數 function keychang(up){ if(up == "up"){ if(indexLi == 1){ indexLi = $(value.divTip).children().length-1; }else{ indexLi--; } }else{ if(indexLi == $(value.divTip).children().length-1){ indexLi = 1; }else{ indexLi++; } } $(value.divTip).children().eq(indexLi).addClass("active").siblings().removeClass(); } //值發生改變時 function valChange(){ var tex = $this.val();//輸入框的值 var fronts = "";//存放含有「@」以前的字符串 var af = /@/; var regMail = new RegExp(tex.substring(tex.indexOf("@")));//有「@」以後的字符串,注意正則字面量方法,是不能用變量的。因此這裏用的是new方式。 //讓提示層顯示,並對裏面的LI遍歷 if($this.val()==""){ blus(); }else{ $(value.divTip). show(). children(). each(function(index) { var valAttr = $(this).attr("email"); if(index==1){$(this).text(tex).addClass("active").siblings().removeClass();} //索引值大於1的LI元素進到處理 if(index>1){ //當輸入的值有「@」的時候 if(af.test(tex)){ //若是含有「@」就截取輸入框這個符號以前的字符串 fronts = tex.substring(tex.indexOf("@"),0); $(this).text(fronts+valAttr); //判斷輸入的值「@」以後的值,是否含有和LI的email屬性 if(regMail.test($(this).attr("email"))){ $(this).show(); }else{ if(index>1){ $(this).hide(); } } } //當輸入的值沒有「@」的時候 else{ $(this).text(tex+valAttr); } } }) } } //輸入框值發生改變的時候執行函數,這裏的事件用判斷處理瀏覽器兼容性; if($.browser.msie){ $(this).bind("propertychange",function(){ valChange(); }) }else{ $(this).bind("input",function(){ valChange(); }) } //鼠標點擊和懸停LI $(value.divTip).children(). hover(function(){ indexLi = $(this).index();//獲取當前鼠標懸停時的LI索引值; if($(this).index()!=0){ $(this).addClass("active").siblings().removeClass(); } }) //按鍵盤的上下移動LI的背景色 $this.keydown(function(event){ if(event.which == 38){//向上 keychang("up") }else if(event.which == 40){//向下 keychang() }else if(event.which == 13){ //回車 var liVal = $(value.divTip).children().eq(indexLi).text(); $this.val(liVal); blus(); } }) } }) })(jQuery)
1、功能分析:
1.input輸入框的值,發生變化時,顯示提示的下拉層;
2.input輸入框的值,發生變化時,顯示提示的下拉層,會根據輸入的內容自動往「@」前面添加;
3.input輸入框的值,發生變化時,顯示提示的下拉層,會根據輸入的內容對下拉層「@」後面的內容進行篩選;
4.點擊下拉層裏面的提示內容,會將其值,填充到輸入框;
5.按下鼠標回車鍵會將其選中的下拉層裏的內容,填充到輸入框;
6.按鍵盤的「向上」或「向下」的方向鍵,能夠在下拉層的選項中移動(循環移動,改變當前LI的背景色);
7.鼠標懸停在下拉層的LI上面時,會有一個背景色。
2、功能實現:
1.input輸入框的值,發生變化時的事件是:propertychange(IE)或input(標準);
2.在發生propertychange事件的時候,取其輸入框的值,再取其「@」前面的值,並賦值給下拉層裏面的LI加上LI的email屬性值;
3.在發生propertychange事件的時候,
3.1取其輸入框的值,再取其「@」後面的值,
3.2並將這個值與下拉層裏面的LI的email屬性值進行正則匹配;
這裏要注意,正則字面量方法,是不能用變量的。因此這裏用的是new方式。
這裏的正則是取的輸入框「@」後面的值,因此正則,是變化的。而LI的EMAIL屬性值是不變的
4.這裏用了一個事件委託方式,將點擊事件綁定給document,而後經過判斷,點擊時最初觸發的DOM元素,是什麼。來決定,
4.1否隱藏下拉提示層?
4.2仍是須要將下拉層,選中的值,賦給輸入框
(這裏不能直接使用,當輸入框失去焦點時,隱藏下拉提示層,由於會與點擊下拉層,將其值填入輸入框,這個功能有邏輯上的矛盾;)
5.和上面第4條差很少;
6.就是要注意,在鼠標懸停時,把當前的LI索引存入一個全局變量當中,這樣就能夠告訴「向上」或「向下」按鍵時,的起始位置了;
7.遍歷LI,給它們的懸停事件都綁定一個改變其當前背景色的處理函數;
感謝「妙味課堂」提供的視頻
在線演示 http://demo.jb51.net/js/2012/myinputMail/
打包下載 myinputMail_jb51.rar瀏覽器