ivony的指导下,我对googlegoogle suggest技术进行了相关的研究。并且取得了一定的成果,基本成功实现了它的功能。下面对其中用js创建其显示效果的控件过程来个总结。
      在这里我先介绍一下实现该控件的过程。我将这个过程为为几个步骤来实现。

      首先触发txt1后,首先对键盘事件进行判断,判断按下键的键值,若按下的键为上下键,则转到执行上下键处理函数 catchKeyBoard();否则转到创建层和层的主体。我们首先来讨论创建层和层主体的问题。要创建层,首先我们要知道它的绝对位置。
1. 获取创建的层的绝对位置。

       要获取创建的层的位置,必须先获取txt1的位置。在这里,我们定义一个函数来获取txt1的位置:

 1function getPosition( obj )
 2
 3     
 4     var top = 0,left = 0;
 5
 6      do 
 7
 8{
 9
10    top += obj.offsetTop;
11
12        left += obj.offsetLeft;
13
14     }

15
16while ( obj = obj.offsetParent );      
17
18      var arr = new Array();      
19
20      arr[0= top;
21
22      arr[1= left;       
23
24      return arr;    
25
26   }

27
28

通过该函数获取txt1的位置为(topleft),则依附txt1创建的层的位置为(top+textbox.clientheightleft),,宽度和txt1相同。

2. 创建层。

    知道了要创建的层的位置,我们要创建一个层就很容易了。

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"); //创建层      

         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"//绝对宽度

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

         newControl.style.top 
= (top_new + textBox.clientHeight + 2+ "px";  //注意,将此高度加2是为了解决JS出现的非自然因素…        

         
return newControl;

       }


       
else

         
return document.getElementById( menuid );

    }


 

3. 创建层的主体

     接下来当然是创建层的主体。在这里为了显示它的效果,我们先定义一些数组,从数组中取数据。

     定义数组:

 

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

   
var arr2=new Array("信乐团","F4","TWINS","SHE","胡彦彬","周杰伦","刘若英","刘德华","angle","orange","green","white","red","blue");

   定义一个函数来取值:

  
function getSearchResult( key )

    
{

      
switch ( key )

      
{

        
case "a":    //当输入a的时候显示arr1里面的数据

          
return arr1;

        
case "s":    //输入s的时候显示arr2里面的数据

          
return arr2;   

        
default:

          
return new Array();

      }
 

}


完成上面这些准备工作后,我们可以正式来创建层的主体了。

 1function createMenuBody( key )
 2
 3    {
 4
 5      var result = "";
 6
 7      var j = 0;
 8
 9      arr = getSearchResult( key ); //获取相应的数组
10
11       //最多显示十行数据
12
13      if(arr.length > 10)
14
15      {
16
17        j = 10;
18
19      }

20
21      else
22
23      {
24
25        j = arr.length;
26
27      }

28
29      for ( var i = 0; i < j; i++ ) //循环创建层的主体
30
31        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>";
32
33       return result;
34
35    }

36
37

 

4. 捕获鼠标事件。

    客观的讲应该是获取层主体的焦点,当主体获取了这个焦点,那么它的颜色变为高亮色。当鼠标移到该主体的时候,它就获取了这个焦点,使该主体变为高亮。换一个角度来思考,变为高亮色这个事件也可以看做是由鼠标触发的。

   因此用onmouseover事件来触发,触发函数forceMenuItem(index).

   先定义一个变量 var menuFocusIndex;它保存的是上一个高亮色的主体的值。触发鼠标事件时,我们将上一个高亮色的主体变为白色,将现在触发的主体变为兰色,就解决了这个问题。代码如下:


 1lastMenuItem = document.getElementById( "menuItem" + menuFocusIndex )
 2
 3       if ( lastMenuItem != null )
 4
 5       {
 6
 7         //将上一个变白
 8
 9         lastMenuItem.style.backgroundColor="white";       
10
11         lastMenuItem.style.color="#000000";
12
13       }

14
15       var menuItem = document.getElementById( "menuItem" + index );
16
17       if ( menuItem == null )
18
19        {
20
21          document.getElementById("txt1").focus(); 
22
23        }

24
25        else 
26
27        {
28
29         menuItem.style.backgroundColor = "#5555CC";
30
31         menuItem.style.color = "#FFFFFF";
32
33         menuFocusIndex = index;
34
35      }

36
37

 

5.捕获上下键事件

   接下来我们解决捕获上下键的问题。这里面一个容易混淆的地方就是,该事件的触发是由txt1来触发的,而不是由层的主体来触发的。事实上围绕这个问题我在实现过程中也走了不少弯路。

   前面我有提到,在触发txt1时即进行判断,如果是上下键即转到上下键处理函数catchKeyBoard()。而不是到创建层。在该函数中,我们也可以调用鼠标事件函数(确切的讲是调用获取焦点函数)。

 

 1Var keyNumber = event.keyCode;
 2
 3if(keyNumber =='40'//向下 
 4
 5      {
 6
 7        if(menuFocusIndex == 10)
 8
 9         return true;
10
11       else if (menuFocusIndex == null//当焦点在文本框中间时,按向下跳到第一个主体。
12
13       {
14
15           forceMenuItem( 1 );
16
17           givNumber( 0 );
18
19       }

20
21       else
22
23       {
24
25          forceMenuItem( menuFocusIndex+1 ); //焦点增加1
26
27          givNumber(menuFocusIndex-1);
28
29       }
 
30
31 
32
33      }

34
35      else if(keyNumber == '38')//向上
36
37      {
38
39        if(menuFocusIndex == 1)
40
41         {
42
43           forceMenuItem(menuFocusIndex-1); //当焦点在第一个主体时,按向上让它回到文本框。
44
45         }

46
47     
48
49        else
50
51        {
52
53          forceMenuItem(menuFocusIndex-1); //焦点减少1
54
55          givNumber(menuFocusIndex-1);
56
57        }
 
58
59      }

60
61

6. 按上下键时给文本框赋对应的值。

  注意到创建层的主体时定义的当前数组的值。就很容易完成这个函数了。

 

 1function givNumber( index )
 2
 3     {
 4
 5       document.getElementById("txt1").value = arr[index];
 6
 7       document.getElementById("txt1").focus();              
 8
 9     }

10
11

 到这里,该控件的主体就基本上完成了,运行,在文本框分别输入as,可以发现它和google suggest的效果是一样的。当然,接下来还要利用AJAX技术进行异步回调,输入查询值的时候由后台从数据库返回查询的数值,做成数组的形式。当然这些简单的步骤我在这里就不多说了。至此,google suggest技术完全得到实现。

posted on 2008-03-13 17:14  亚辉  阅读(137)  评论(0)    收藏  举报