// 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.input输入框的值,发生变化时,显示提示的下拉层;
  2.input输入框的值,发生变化时,显示提示的下拉层,会根据输入的内容自动往“@”前面添加;
  3.input输入框的值,发生变化时,显示提示的下拉层,会根据输入的内容对下拉层“@”后面的内容进行筛选;
  4.点击下拉层里面的提示内容,会将其值,填充到输入框;
  5.按下鼠标回车键会将其选中的下拉层里的内容,填充到输入框;
  6.按键盘的“向上”或“向下”的方向键,可以在下拉层的选项中移动(循环移动,改变当前LI的背景色);
  7.鼠标悬停在下拉层的LI上面时,会有一个背景色。
二、功能实现:
  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,给它们的悬停事件都绑定一个改变其当前背景色的处理函数;