在这里我先介绍一下实现该控件的过程。我将这个过程为为几个步骤来实现。
首先触发txt1后,首先对键盘事件进行判断,判断按下键的键值,若按下的键为上下键,则转到执行上下键处理函数 catchKeyBoard();否则转到创建层和层的主体。我们首先来讨论创建层和层主体的问题。要创建层,首先我们要知道它的绝对位置。
1. 获取创建的层的绝对位置。
要获取创建的层的位置,必须先获取txt1的位置。在这里,我们定义一个函数来获取txt1的位置:
function 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

16
while ( 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的位置为(top,left),则依附txt1创建的层的位置为(top+textbox.clientheight,left),,宽度和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();
} 
}

完成上面这些准备工作后,我们可以正式来创建层的主体了。
function 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
else22

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;它保存的是上一个高亮色的主体的值。触发鼠标事件时,我们将上一个高亮色的主体变为白色,将现在触发的主体变为兰色,就解决了这个问题。代码如下:
lastMenuItem = 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()。而不是到创建层。在该函数中,我们也可以调用鼠标事件函数(确切的讲是调用获取焦点函数)。
Var keyNumber = event.keyCode;2

3
if(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
else22

23
{24

25
forceMenuItem( menuFocusIndex+1 ); //焦点增加126

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
else50

51
{52

53
forceMenuItem(menuFocusIndex-1); //焦点减少154

55
givNumber(menuFocusIndex-1);56

57
} 58

59
}60

61

6. 按上下键时给文本框赋对应的值。
注意到创建层的主体时定义的当前数组的值。就很容易完成这个函数了。
function givNumber( index )2

3
{4

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

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

9
}10

11

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


浙公网安备 33010602011771号