DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> AJAX入門 >> AJAX詳解 >> 利用PHP+JavaScript打造AJAX搜索窗
利用PHP+JavaScript打造AJAX搜索窗
編輯:AJAX詳解     
一、 引言

  Web世界中一項廣為使用的功能就是搜索。隨著Web技術的日益發展,為了更好地滿足客戶的需求,常規搜索引擎開始對更多的非常規方式"敞開了大門"。在這方面,Yahoo!率先提供出其Y!Q服務。這個新的服務能夠使你搜索任何web頁面,前提是該頁面的作者必須包括在他們的web頁面中。是服務技術實現了把相關的搜索結果呈現到讀者眼前,從而向讀者展示更多的信息而不必離開他們的當前頁面。

  Yahoo!的Y!Q服務的確是一個偉大的想法,但是它的出現也受到了一些批評。原因何在?首先,它要求客戶端必須使用Yahoo!的JavaScript並且你必須添加一個<form/>元素,以便滿足Yahoo!的搜索要求。對於許多網站作者來說,提供該服務要求付出太多的努力。並且,在所有這些條件滿足之後,搜索結果將以Yahoo!風格展現,從而破壞了用戶網站的外觀感覺。

  幸運的是,Yahoo!並非唯一的提供"從你的網站提供搜索結果"服務的搜索引擎。MSN Search也提供一種類似服務,除了它能夠使web開發者控制外觀感覺以外。這種能力來自於MSN Search提供它的搜索結果的RSS版本,從而使得訂閱一個特定的搜索或使用AJax方法把該結果添加到你的頁面成為可能。

  盡管Google已經率先實現了這種新的"從你的站點進行搜索"技術;但是,在本文成文之時,與Google相關的Google BlogSearch Beta也已經能夠以RSS或者Atom格式提供返回的結果。

  二、 服務器端組件

  使用MSN Search執行搜索時,你會看到一個桔黃.色的XML圖像出現在結果頁面的底部。點擊這個圖像將會把你帶到一個新的頁面,並提供給你訂閱該搜索的URL。

  這樣以來,你就可以編寫服務器端代碼以檢索遠程饋送。對於本文中的搜索窗,你將使用PHP檢索搜索饋送。來自於服務器應用程序請求信息的URL看起來如下所示:

websearch.PHP?search=[SEARCHTERM]
  查詢字符串只有一個變量:"search";因此,應用程序應該查找此查詢項。在服務器端,你需要創建一個頁面來"拉動"這個數據:

<?PHP
header("Content-Type: text/XML");
header("Cache-Control: no-cache");if ( isset($_GET["search"]) )
{
 $searchTerm = urlencode( stripslashes($_GET["search"]) );
 $url = "http://search.msn.com/results.ASPx?q=$searchTerm&format=rss";
 $XML = file_get_contents($url);
 echo $XML;
}
?>
  前兩行設置要求的頭部以便浏覽器能夠正確處理數據(XML形式,並且沒有對結果予以緩沖)。下一行代碼使用isset()函數來決定是否搜索鍵存在於查詢字符串中。

  為了把一個合適的請求發送到遠程主機,搜索術語應該通過許多函數的"過濾"。首先,它被傳遞給stripslashes()函數。如果在PHP配置中啟動了"magic quotes"(缺省情況下是支持的),那麼,到達PHP引擎的任何引號都會被使用一個斜槓(如,\"search query\")自動地脫掉。該stripslashes()函數負責刪除這些符號,僅留下"search query"。在刪除斜槓後,轉到urlencode()函數,由這個函數負責編碼字符以用於查詢字符串。空格、引號、"&"等符號都被編碼。

  注意 如果搜索術語不能通過這些函數的"過濾",那麼,MSN服務器將返回一個代碼400-"Bad Request"。

  當為轉換搜索術語准備好後,它被包括到URL中並存儲於$url變量中。最後,file_get_contents()函數負責打開遠程文件,讀取其內容並以一個字符串形式把它返回到$XML變量中,然後使用echo命令把它打印到頁面中。

  三、 客戶端組件

  本文中的搜索窗口(Widget)的客戶端代碼基於一個靜態對象msnWebSearch創建-它被定義為一個沒有任何屬性(現在)的對象:

var msnWebSearch ={};
  這個對象用於一個HtmlElement的onclick事件中執行搜索:

<a href="#"
onclick='msnWebSearch.search(event,"Professional AJax"); return false;'>
Professional AJax
</a>
  這個msnWebSearch對象提供若干取得搜索結果的方法,並負責繪制和放置包含這些數據的HTML。第一個方法是drawResultBox(),它負責繪制HTML。這個方法形成的Html如下所示:

<divclass="AJaxWebSearchBox">
 <div class="AJaxWebSearchHeading">MSN Search Results
 <a class="AJaxWebSearchCloseLink" href="#">X</a>
</div>
<div class="AJaxWebSearchResults">
 <a class="AJaxWebSearchLink" target="_new" />
 <a class="AJaxWebSearchLink" target="_new" />
</div>
</div>
  該結果框分為兩部分:一個頭部和一個結果欄(見圖1)。頭部告訴用戶這個新的搜索窗包含來自一個MSN搜索的結果。它還包含一個"X"用於關閉該小窗口。其結果欄包含塊風格的鏈接,當點擊這些鏈接時將打一個新的窗口。


圖1.結果框分為兩部分:一個頭部和一個結果欄  四、 繪制結果用戶接口

  生成這個Html的代碼相當長,因為其中的元素都是使用DOM方法生成的。drawResultBox()方法接受一個參數(一個事件對象):

msnWebSearch.drawResultBox = function (e) {
 var divSearchBox= document.createElement("div");
 var divHeading = document.createElement("div");
 var divResultsPane = document.createElement("div");
 var aCloseLink = document.createElement("a");
  前面這些代碼經由createElement()方法創建Html元素。在創建這些元素後,你就能夠開始賦予它們屬性。上面完成終結(封尾)的兩個元素分別是aCloseLink和divHeading:

aCloseLink.href = "#";
aCloseLink.className = "AJaxWebSearchCloseLink";
aCloseLink.onclick = this.close;
aCloseLink.appendChild(document.createTextNode("X"));
divHeading.className = "AJaxWebSearchHeading";
divHeading.appendChild(document.createTextNode("MSN Search Results"));
divHeading.appendChild(aCloseLink);
  前四行完成關閉結果框的鏈接。其中,方法close()成為鏈接的onclick事件的處理器。後面的幾行代碼負責使用文本和關閉鏈接填充頭部的<div/>。

  當這個結果框被繪制到頁面上時,還沒有接收到來自於一個服務器應用程序的響應。為了向用戶展示已經發生了什麼,可以向用戶展示一個消息提示數據正在加載中(這種方式更友好些)(見圖2)。為此,創建另一個元素並且把它添加到divResultsPane元素:

var divLoading = document.createElement("div");
divLoading.appendChild(document.createTextNode("Loading Search Feed"));

divResultsPane.className = "AJaxWebSearchResults";
divResultsPane.appendChild(divLoading);
  這個代碼創建加載消息並且把它添加到divResultsPane,同時還把類名賦給divResultsPane。


圖2.向用戶提示數據正在加載中
  完成這些元素之後,剩下的就是把它們添加到divSearchBox元素中:

divSearchBox.className = "AJaxWebSearchBox";
divSearchBox.appendChild(divHeading);
divSearchBox.appendChild(divResultsPane);
document.body.appendChild(divSearchBox);
  這段代碼負責把divHeading和divResultsPane元素添加到搜索窗,並且把搜索窗添加到頁面。

  在drawResultBox()中的最後一步是確定新繪制的小框的位置並且把divSearchBox返回到它的調用者:

msnWebSearch.drawResultBox = function (e) {
 var divSearchBox= document.createElement("div");
 var divHeading = document.createElement("div");
 var divResultsPane = document.createElement("div");
 var aCloseLink = document.createElement("a");
 aCloseLink.href = "#";
 aCloseLink.className = "AJaxWebSearchCloseLink";
 aCloseLink.onclick = this.close;
 aCloseLink.appendChild(document.createTextNode("X"));
 divHeading.className = "AJaxWebSearchHeading";
 divHeading.appendChild(document.createTextNode("MSN Search Results"));
 divHeading.appendChild(aCloseLink);
 var divLoading = document.createElement("div");
 divLoading.appendChild(document.createTextNode("Loading Search Feed"));
 divResultsPane.className = "AJaxWebSearchResults";
 divResultsPane.appendChild(divLoading);
 divSearchBox.className = "AJaxWebSearchBox";
 divSearchBox.appendChild(divHeading);
 divSearchBox.appendChild(divResultsPane);
 document.body.appendChild(divSearchBox);
 this.position(e, divSearchBox);
 return divSearchBox;
};
  通過這種方式建立msnWebSearch對象後,必須把divSearchBox返回到它的調用者以便進行其它操作。你可以已經猜出,position()方法負責放置該搜索框。它接受兩個參數:傳遞到drawResultBox()的事件對象和divSearchBox元素:

msnWebSearch.position = function (e, divSearchBox) {
 var x = e.clIEntX + document.documentElement.scrollLeft;
 var y = e.clIEntY + document.documentElement.scrollTop;
 divSearchBox.style.left = x + "px";
 divSearchBox.style.top = y + "px";
};
  前兩行代碼得到左邊和頂部位置,用於放置搜索結果框。執行這個操作要求使用兩種信息。首先是鼠標的x和y坐標(這些信息被存儲在clientX和clIEntY屬性)。

  然而,這些坐標還不足以正確定位結果框,因為clientX和clIEntY屬性返回相對於浏覽器窗口客戶區的鼠標位置,而不是頁面中的實際坐標。考慮到這一點,我們可以使用文檔元素的scrollLeft和scrollTop屬性。計算出最後的坐標後,你能夠最後確定用戶點擊鼠標的框中的位置。
  五、 顯示結果

  populateResults()方法負責使用搜索結果填充結果欄。它接受兩個參數:包含該結果的元素和一個XParser對象(XParser是一個基於Javascript的RSS讀取器,可從www.wdonline.com/Javascript/xparser/自由下載):

msnWebSearch.populateResults = function(divResultsPane,oParser){
 var oFragment = document.createDocumentFragment();

 divResultsPane.removeChild(divResultsPane.firstChild);
  這個方法以編程方式並通過DOM方法生成<a/>元素;這樣以來,這些元素將被添加到一個在第一行創建的文檔片斷中。下一行刪除添加在drawResultBox()中的正加載的<div/>元素。

  下一步是創建這個鏈接:

for (var i = 0; i < oParser.items.length; i++) {
 var oItem = oParser.items[i];

 var aResultLink = document.createElement("a");
 aResultLink.href = oItem.link.value;
 aResultLink.className = "AJaxWebSearchLink";
 aResultLink.target = "_new";
 aResultLink.appendChild(document.createTextNode(oItem.title.value));

 oFragment.appendChild(aResultLink);
}
  這段代碼遍歷回饋的各個項,並且由該數據生成鏈接並把<a/>元素添加到文檔片斷最後。

  當退出循環時,該文檔片斷被添加到divResultsPane以顯示搜索結果:

divResultsPane.appendChild(oFragment);
  六、 關閉結果框

  為了關閉搜索結果框,msnWebSearch對象提供了close()方法。close()方法負責處理該鏈接的onclick事件(關閉該小框):

msnWebSearch.close = function () {
 var divSearchBox = this.parentNode.parentNode;
 document.body.removeChild(divSearchBox);

 return false;
};
  該搜索框其實並沒有關閉;事實上,它被從該文檔中刪除了。為此,需要檢索divSearchBox元素。第一行代碼完成這一任務-通過檢索這個元素的父結點的父結點實現。因為close()負責處理onclick事件,所以this引用這一鏈接。下一行從文檔中刪除divSearchBox元素。最後一行,返回false,從而強迫浏覽器不要沿用一個鏈接的缺省行為(轉到在href屬性中標注的位置)。

  七、 構建搜索接口

  msnWebSearch對象的最後一個方法是search(),它提供執行一個搜索的接口。你可以使用一個元素的onclick事件來調用search()。它接受兩個方法:一個事件對象和搜索術語:

msnWebSearch.search = function (e,sSearchTerm) {
 var divSearchBox = this.drawResultBox(e);
 var url = encodeURI("websearch.PHP?search=" + sSearchTerm);
 var oParser = new XParser(url);
 oParser.onload = function () {
  msnWebSearch.populateResults(divSearchBox.childNodes[1],oParser);
 };
};


  第一行調用drawResultBox()方法並且把事件e傳遞給它。下一行編碼該URL以實現合適的轉換。這個URL被傳遞給XParser構造器以創建一個新的分析器。當搜索回饋完成加載並使用結果填充搜索框時,該分析器的onload事件處理器調用populateResult()方法。
當然,構建這個搜索框的一個理由是,使其更適合於你自己的站點的外觀。

  八、 定制Web搜索框

  借助於CSS,你可以容易地為你的現有站點定制搜索框,並且使你以後的任何重新設計都變得非常容易。

  首先要討論的CSS類是AJaxWebSearchBox(該類實現搜索框)。因為搜索框要確定位置,所以它必須要有一個絕對位置:

.AJaxWebSearchBox
{
 position: absolute;
 background-color: #0d1e4a;
 width: 500px;
 padding: 1px;
}
  在此,絕對位置是唯一的要求。所有的其它屬性都是根據你的口味可選的。在這個示例中,該框有一個微藍色的背景,一個500像素的寬度,以及在四邊上各有1個像素的填充。這個填充導致圍繞該框的內容的是1個像素寬的邊界。

  下一個類是ajaxWebSearchHeading,它包含該框的頭部文本和關閉鏈接。為了把關閉鏈接放在右上角,它使用絕對位置。因為這個原因,它要求AJaxWebSearchHeading使用一個相對位置:

.AJaxWebSearchHeading
{
 position: relative;
 background-color: #1162cc;
 font: bold 14px tahoma;
 height: 21px;
 color: white;
 padding: 3px 0px 0px 2px;
}
  在此,唯一要求的屬性也是position屬性。其它的屬性有助於給出該元素一個好看的外觀。其背景顏色是淺藍色,而文本部分是白色,14像素高且是Tahoma字體。該元素的高度是21個像素並且在頂部和左邊都填充以邊界。

  如前面所述,該關閉鏈接的位置是絕對的:

a.AJaxWebSearchCloseLink
{
 position: absolute;
 right: 5px;
 top: 3px;
 text-decoration: none;
 color: white;
}
a:hover.AJaxWebSearchCloseLink
{
 color: red;
}
  該元素被放置在距右邊5個像素,距頂部3個像素的位置(該元素被放在右上角)。這個鏈接沒有任何文本修飾並且顏色呈白色。當用戶的鼠標停在該鏈接上時,文本顏色變紅。

  注意,這裡沒有使用訪問過的或活動的"假"類。這是因為該窗口總是忽略這個鏈接的href屬性(它已經在它的事件處理器中返回了false)。因此,該鏈接從來不會真正處於活動或被訪問狀態。

  然後,AJaxWebSearchResults類使結果欄的風格如下:

.AJaxWebSearchResults
{
 background-color: #d3e5fa;
 padding: 5px;
}
  這個元素不要求使用CSS屬性。現有屬性僅用於定義結果欄並且使它比較容易讀取。背景顏色是一個淺藍色並且圍繞邊緣有5個像素的填充。當然,你能夠定制加載消息的風格:

.AJaxWebSearchResults div
{
 text-align: center;
 font: bold 14px tahoma;
 color:#0a246a;
}
  這個元素沒有一個類名,但是你仍然能夠通過使用前面的示例中展示的parent child標志控制它的風格。這個示例把文本放置在<div/>元素的中央,並且給它一個加粗藍色的字體,且有14個像素高。

  最後一個你需要風格化的元素是結果鏈接。這些鏈接有一個類名叫AJaxWebSearchLink:

a.AJaxWebSearchLink
{
 font: 12px tahoma;
 padding: 2px;
 display: block;
 color: #0a246a;
}
a:hover.AJaxWebSearchLink
{
 color: white;
 background-color: #316ac5;
}
a:visited.AJaxWebSearchLink
{
 color: purple;
}
  唯一要求的屬性是display屬性(被設置為block)。這使每一個鏈接都能夠在它自己的行上顯示。填充空白部分大約有兩個像素寬,使各個鏈接之間分開一些,從而使它們更易於讀取。字體名為Tahoma並且有12像素高。它們的顏色是暗藍色,與AJaxWebSearchResults的淺藍色背景形成對照。

  當用戶在這些鏈接上移動鼠標時,背景顏色被設置為藍色,而文本顏色改變為白色。

  在前面的代碼的最後一條規則中訪問過的"假"類被設置。這是為了給用戶提供用戶接口暗示-它們已經被使用過。通過把訪問過的"假"類設置為顯示一種紫色,用戶就可以知道它們已經訪問過那個鏈接,從而節省他們的時間-不必再訪問一個他們可能不想看的頁面。

  現在,讓我們來看一下如何實現搜索框。

  九、 實現Web搜索搜索框

  實現這個搜索框是很簡單的。首先,你必須把websearch.php文件上傳到你的web服務器(當然,必須安裝PHP)。然後,你需要一個Html文檔來引用所有的組件。msnWebSearch對象依賴於XParser類,這個類又依賴於zXML庫(可從www.nczonline.Net/downloads/下載)。你必須引用下面這些文件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHtml 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xHtml1-transitional.dtd">
<html xml:lang="en" lang="en" XMLns="http://www.w3.org/1999/xHtml">
<head>
<meta http-equiv="Content-Type" content="text/Html; charset=utf-8" />
<title>AJax WebSearch</title>
<link rel="stylesheet" type="text/css" href="css/websearch.CSS" />
<script type="text/Javascript" src="JS/zXML.JS"></script>
<script type="text/Javascript" src="js/xparser.JS"></script>
<script type="text/Javascript" src="js/websearch.JS"></script>
</head><body>
</body>
</Html>
  為了執行搜索,應該把msnWebSearch.search()方法設置為該元素的onclick處理器:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHtml 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xHtml1-transitional.dtd">
<html xml:lang="en" lang="en" XMLns="http://www.w3.org/1999/xHtml">
<head>
<meta http-equiv="Content-Type" content="text/Html; charset=utf-8" />
<title>AJax WebSearch</title>
<link rel="stylesheet" type="text/css" href="css/websearch.CSS" />
<script type="text/Javascript" src="JS/zXML.JS"></script>
<script type="text/Javascript" src="js/xparser.JS"></script>
<script type="text/Javascript" src="js/websearch.JS"></script>
</head><body>
<a href="#" onclick='msnWebSearch.search(event,"\"Professional AJax\"");
return false;'>Search for "Professional AJax"</a>
<br /><br /><br /><br />
<a href="#" onclick='msnWebSearch.search(event,"Professional AJax");
return false;'>Search for Professional AJax</a>
</body>
</Html>
  第一個新的鏈接執行一個針對准確詞組"Professional AJax"的搜索,而第二個鏈接將搜索這其中的各個單詞。還要注意,在onclick事件中返回的是false-這強迫浏覽器忽略掉href屬性。點擊這些鏈接將在光標位置繪制搜索框,並且就在此處顯示你的搜索結果。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved