首先觸發
txt1后,首先對鍵盤事件進行判斷,判斷按下鍵的鍵值,若按下的鍵為上下鍵,則轉到執行上下鍵處理函數
catchKeyBoard();否則轉到創建層和層的主體。我們首先來討論創建層和層主體的問題。要創建層,首先我們要知道它的絕對位置。
1. 獲取創建的層的絕對位置。
要獲取創建的層的位置,必須先獲取txt1的位置。在這里,我們定義一個函數來獲取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;
}
通過該函數獲取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 )
{
var result = "";
var j = 0;
arr = getSearchResult( key ); //獲取相應的數組
//最多顯示十行數據
if(arr.length > 10)
{
j = 10;
}
else
{
j = arr.length;
}
for ( var i = 0; i < j; i++ ) //循環創建層的主體
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. 捕獲鼠標事件。
客觀的講應該是獲取層主體的焦點,當主體獲取了這個焦點,那么它的顏色變為高亮色。當鼠標移到該主體的時候,它就獲取了這個焦點,使該主體變為高亮。換一個角度來思考,變為高亮色這個事件也可以看做是由鼠標觸發的。
因此用onmouseover事件來觸發,觸發函數forceMenuItem(index).
先定義一個變量 var menuFocusIndex;它保存的是上一個高亮色的主體的值。觸發鼠標事件時,我們將上一個高亮色的主體變為白色,將現在觸發的主體變為蘭色,就解決了這個問題。代碼如下:
lastMenuItem = document.getElementById( "menuItem" + menuFocusIndex )
if ( lastMenuItem != null )
{
//將上一個變白
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.捕獲上下鍵事件
接下來我們解決捕獲上下鍵的問題。這里面一個容易混淆的地方就是,該事件的觸發是由txt1來觸發的,而不是由層的主體來觸發的。事實上圍繞這個問題我在實現過程中也走了不少彎路。
前面我有提到,在觸發txt1時即進行判斷,如果是上下鍵即轉到上下鍵處理函數catchKeyBoard()。而不是到創建層。在該函數中,我們也可以調用鼠標事件函數(確切的講是調用獲取焦點函數)。
Var keyNumber = event.keyCode;
if(keyNumber =='40') //向下
{
if(menuFocusIndex == 10)
return true;
else if (menuFocusIndex == null) //當焦點在文本框中間時,按向下跳到第一個主體。
{
forceMenuItem( 1 );
givNumber( 0 );
}
else
{
forceMenuItem( menuFocusIndex+1 ); //焦點增加1
givNumber(menuFocusIndex-1);
}
}
else if(keyNumber == '38')//向上
{
if(menuFocusIndex == 1)
{
forceMenuItem(menuFocusIndex-1); //當焦點在第一個主體時,按向上讓它回到文本框。
}
else
{
forceMenuItem(menuFocusIndex-1); //焦點減少1
givNumber(menuFocusIndex-1);
}
}
6. 按上下鍵時給文本框賦對應的值。
注意到創建層的主體時定義的當前數組的值。就很容易完成這個函數了。
function givNumber( index )
{
document.getElementById("txt1").value = arr[index];
document.getElementById("txt1").focus();
}
到這里,該控件的主體就基本上完成了,運行,在文本框分別輸入a和s,可以發現它和google suggest的效果是一樣的。當然,接下來還要利用AJAX技術進行異步回調,輸入查詢值的時候由后臺從數據庫返回查詢的數值,做成數組的形式。當然這些簡單的步驟我在這里就不多說了。至此,google suggest技術完全得到實現。
開心過好每一天。。。。。