首先觸發(fā)txt1后,首先對(duì)鍵盤事件進(jìn)行判斷,判斷按下鍵的鍵值,若按下的鍵為上下鍵,則轉(zhuǎn)到執(zhí)行上下鍵處理函數(shù) catchKeyBoard();否則轉(zhuǎn)到創(chuàng)建層和層的主體。我們首先來(lái)討論創(chuàng)建層和層主體的問(wèn)題。要?jiǎng)?chuàng)建層,首先我們要知道它的絕對(duì)位置。

 1. 獲取創(chuàng)建的層的絕對(duì)位置。

       要獲取創(chuàng)建的層的位置,必須先獲取txt1的位置。在這里,我們定義一個(gè)函數(shù)來(lái)獲取txt1的位置:

 function getPosition( obj )

    
     var top = 0,left = 0;

      do

{

    top += obj.offsetTop;

        left += obj.offsetLeft;

     }

while ( obj = obj.offsetParent );     

      var arr = new Array();     

      arr[0] = top;

      arr[1] = left;      

      return arr;   

   }

     通過(guò)該函數(shù)獲取txt1的位置為(topleft),則依附txt1創(chuàng)建的層的位置為(top+textbox.clientheightleft),,寬度和txt1相同。

2. 創(chuàng)建層。

    知道了要?jiǎng)?chuàng)建的層的位置,我們要?jiǎng)?chuàng)建一個(gè)層就很容易了。

function createMenu( textBox, menuid )

    {

       if( document.getElementById( menuid ) == null )

       {

         var left_new=getPosition( textBox )[1]

         var top_new=getPosition( textBox )[0];         

         var newControl = document.createElement("div"); //創(chuàng)建層     

         newControl.id = menuid;       

         document.body.appendChild( newControl );      

         newControl.style.position = "absolute"

         newControl.style.border = "solid 1px #000000";

         newControl.style.backgroundColor = "#FFFFFF";

         newControl.style.width = textBox.clientWidth + "px"; //絕對(duì)寬度

         newControl.style.left = left_new + "px";           //位置

         newControl.style.top = (top_new + textBox.clientHeight + 2) + "px";  //注意,將此高度加2是為了解決JS出現(xiàn)的非自然因素        

         return newControl;

       }

       else

         return document.getElementById( menuid );

    }

3. 創(chuàng)建層的主體

     接下來(lái)當(dāng)然是創(chuàng)建層的主體。在這里為了顯示它的效果,我們先定義一些數(shù)組,從數(shù)組中取數(shù)據(jù)。

     定義數(shù)組:

  var arr1=new Array("alizee","westlife","john","blue","colinton","angle");

   var arr2=new Array("信樂(lè)團(tuán)","F4","TWINS","SHE","胡彥彬","周杰倫","劉若英","劉德華","angle","orange","green","white","red","blue");

   定義一個(gè)函數(shù)來(lái)取值:

  function getSearchResult( key )

    {

      switch ( key )

      {

        case "a":    //當(dāng)輸入a的時(shí)候顯示arr1里面的數(shù)據(jù)

          return arr1;

        case "s":    //輸入s的時(shí)候顯示arr2里面的數(shù)據(jù)

          return arr2;  

        default:

          return new Array();

     

}

  完成上面這些準(zhǔn)備工作后,我們可以正式來(lái)創(chuàng)建層的主體了。

  function createMenuBody( key )

    {

      var result = "";

      var j = 0;

      arr = getSearchResult( key ); //獲取相應(yīng)的數(shù)組

       //最多顯示十行數(shù)據(jù)

      if(arr.length > 10)

      {

        j = 10;

      }

      else

      {

        j = arr.length;

      }

      for ( var i = 0; i < j; i++ ) //循環(huán)創(chuàng)建層的主體

        result += "<table border=\"0\" cellpadding=\"2\" cellspacing=\"0\" id=\"menuItem"+(i+1)+"\" onmouseover=\"forceMenuItem( "+(i+1)+");\" width=\"100%\" onclick=\"givNumber("+i+")\"><tr><td align=\"left\">" + arr[i] + "</td><td align=\"right\">" + (i+1) + " </td></tr></table>";

       return result;

    }

4. 捕獲鼠標(biāo)事件。

    客觀的講應(yīng)該是獲取層主體的焦點(diǎn),當(dāng)主體獲取了這個(gè)焦點(diǎn),那么它的顏色變?yōu)楦吡辽.?dāng)鼠標(biāo)移到該主體的時(shí)候,它就獲取了這個(gè)焦點(diǎn),使該主體變?yōu)楦吡痢Q一個(gè)角度來(lái)思考,變?yōu)楦吡辽@個(gè)事件也可以看做是由鼠標(biāo)觸發(fā)的。

   因此用onmouseover事件來(lái)觸發(fā),觸發(fā)函數(shù)forceMenuItem(index).

   先定義一個(gè)變量 var menuFocusIndex;它保存的是上一個(gè)高亮色的主體的值。觸發(fā)鼠標(biāo)事件時(shí),我們將上一個(gè)高亮色的主體變?yōu)榘咨瑢F(xiàn)在觸發(fā)的主體變?yōu)樘m色,就解決了這個(gè)問(wèn)題。代碼如下:

lastMenuItem = document.getElementById( "menuItem" + menuFocusIndex )

       if ( lastMenuItem != null )

       {

         //將上一個(gè)變白

         lastMenuItem.style.backgroundColor="white";      

         lastMenuItem.style.color="#000000";

       }

       var menuItem = document.getElementById( "menuItem" + index );

       if ( menuItem == null )

        {

          document.getElementById("txt1").focus();

        }

        else

        {

         menuItem.style.backgroundColor = "#5555CC";

         menuItem.style.color = "#FFFFFF";

         menuFocusIndex = index;

      }

5.捕獲上下鍵事件

   接下來(lái)我們解決捕獲上下鍵的問(wèn)題。這里面一個(gè)容易混淆的地方就是,該事件的觸發(fā)是由txt1來(lái)觸發(fā)的,而不是由層的主體來(lái)觸發(fā)的。事實(shí)上圍繞這個(gè)問(wèn)題我在實(shí)現(xiàn)過(guò)程中也走了不少?gòu)澛贰?/span>

   前面我有提到,在觸發(fā)txt1時(shí)即進(jìn)行判斷,如果是上下鍵即轉(zhuǎn)到上下鍵處理函數(shù)catchKeyBoard()。而不是到創(chuàng)建層。在該函數(shù)中,我們也可以調(diào)用鼠標(biāo)事件函數(shù)(確切的講是調(diào)用獲取焦點(diǎn)函數(shù))。

Var keyNumber = event.keyCode;

if(keyNumber =='40') //向下

      {

        if(menuFocusIndex == 10)

         return true;

       else if (menuFocusIndex == null) //當(dāng)焦點(diǎn)在文本框中間時(shí),按向下跳到第一個(gè)主體。

       {

           forceMenuItem( 1 );

           givNumber( 0 );

       }

       else

       {

          forceMenuItem( menuFocusIndex+1 ); //焦點(diǎn)增加1

          givNumber(menuFocusIndex-1);

       }

 

      }

      else if(keyNumber == '38')//向上

      {

        if(menuFocusIndex == 1)

         {

           forceMenuItem(menuFocusIndex-1); //當(dāng)焦點(diǎn)在第一個(gè)主體時(shí),按向上讓它回到文本框。

         }

    

        else

        {

          forceMenuItem(menuFocusIndex-1); //焦點(diǎn)減少1

          givNumber(menuFocusIndex-1);

        }

      }

6. 按上下鍵時(shí)給文本框賦對(duì)應(yīng)的值。

  注意到創(chuàng)建層的主體時(shí)定義的當(dāng)前數(shù)組的值。就很容易完成這個(gè)函數(shù)了。

 function givNumber( index )

     {

       document.getElementById("txt1").value = arr[index];

       document.getElementById("txt1").focus();             

     }

   到這里,該控件的主體就基本上完成了,運(yùn)行,在文本框分別輸入as,可以發(fā)現(xiàn)它和google suggest的效果是一樣的。當(dāng)然,接下來(lái)還要利用AJAX技術(shù)進(jìn)行異步回調(diào),輸入查詢值的時(shí)候由后臺(tái)從數(shù)據(jù)庫(kù)返回查詢的數(shù)值,做成數(shù)組的形式。當(dāng)然這些簡(jiǎn)單的步驟我在這里就不多說(shuō)了。至此,google suggest技術(shù)完全得到實(shí)現(xiàn)。



開(kāi)心過(guò)好每一天。。。。。