国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > AJAX > 正文

實例解析Ajax標簽導航-DOM技巧篇

2024-09-01 08:26:25
字體:
來源:轉載
供稿:網(wǎng)友

DOM技巧篇(DOM基礎知識)

講到這里,我們就要了解一下DOM的一些基礎知識了。

DOM(Document Object Model 文檔對象模型)是HTML和XML的應用程序接口(API)。DOM將把整個頁面規(guī)劃成有節(jié)點層級構成的文檔。HTML或XML頁面的每一個部分都是一個節(jié)點的衍生物。

光說可能還不怎么好理解,那么來看看我們ajax標簽導航的DOM結構吧,如圖五(截取的FIXFOX中的DOM圖象):

DOM通過創(chuàng)建樹來表示文檔,從而使開發(fā)著對文檔的內容和結構具有空前的控制力。用DOM API可以輕松地刪除,添加和替換節(jié)點。

簡單的了解了什么是DOM后(要想了解更多的Javascript DOM 編程知識,推薦大家看看《Javascript DOM 編程藝術》和《Javascript高級編程》這兩本書,還有到作者的網(wǎng)站去看看,也可以直接到W3C去查詢相關信息。),來看看我們這個程序里需要用到的DOM知識吧:document.getElementsByTagName()還有之前提到的(i)函數(shù),它們都是做什么用的呢?

document.getElementById("DOMId"):它返回的是以ID為表示的節(jié)點,而大家都知道id在頁面中是唯一的,所以getElementById是在頁面中搜索DOM節(jié)點最直接的方法,很常用。不過它只能查尋單個的DOM節(jié)點,我們要查詢一組怎么辦呢? 我們可以使用getElementsByTagName和getElementsByName。

從方法名字中的“Elements”我們也可以知道,這兩個方法返回的是一組元素(數(shù)組)

getElementsByTagName:(核心[XML]DOM)用來返回一個包含所有tagName(標簽名)特性等于某個指定值的元素的NodeList。

getElementsByName:(HTML DOM)用來獲取所有name特性等于指定值的元素。但是這個方法在IE6和opera7.5中支持不是很好,會有錯誤產(chǎn)生,所以(個人)建議一般不要用。

OK,在對使用DOM來查尋節(jié)點的知識有了了解后,我們再來看這段代碼:

/* ===========================================================
* 函數(shù)名稱:(i)
* 參數(shù)說明:i - 目標節(jié)點名稱
* 函數(shù)功能:獲取指定的目標DOM節(jié)點
* 返 回 值:返回要搜索的目標DOM節(jié)點
* 使用方法:("frmSearch")
============================================================ */
function (i){
if(!document.getElementById)return false;
if(typeof i==="string"){
if(document.getElementById && document.getElementById(i)) {
// W3C DOM
return document.getElementById(i);
}
else if (document.all && document.all(i)) {
// MSIE 4 DOM
return document.all(i);
}
else if (document.layers && document.layers[i]) {
// NN 4 DOM.. note: this won't find nested layers
return document.layers[i];
}
else {
return false;
}
}
else{return i;}
}

這個函數(shù)主要是來查找指定的DOM節(jié)點的,主要是通過document.getElementById()方法,但是我們又看到了document.all()和document.layers[]方法,這個就是瀏覽器大戰(zhàn)時期(各個瀏覽器對DOM標準支持不程度不同),各大瀏覽器提供商制定的各自的DOM支持規(guī)范而造成的,我們的CSS HACKS其實也是由于這個原因才會出現(xiàn)的。扯遠了,document.all()是IE瀏覽器(IE5以上版本)中特有的查詢節(jié)點的方法,而document.layers[i]則是其他瀏覽器(主要是NetScape的)的瀏覽器特有的。我們通過(i)函數(shù)來統(tǒng)一調用,從而解決了瀏覽器兼容的問題。

而下面這里的代碼:

// DOM節(jié)點(tabs)不存在或者瀏覽器不支持getElementsByTagName()函數(shù)不執(zhí)行
if(!tabs || !document.getElementsByTagName) return false;

這里if(!tabs || !document.getElementsByTagName) return false;這么寫是很有必要的,這里是一種預留退路的思想(在《Javascript DOM 編程藝術》一書一直灌輸?shù)乃枷耄@么寫在不支持getElementsByTagName()方法時我們的函數(shù)就不會執(zhí)行,在不tabs(("news")和("sports")),不存在的時候(可能是我們把參數(shù)名寫錯了),函數(shù)也不執(zhí)行了,從而避免了彈出或顯示腳本錯誤的信息。下面我們還將看到這一思想的體現(xiàn),不過我們還是先來看看緊接的代碼:

var theList = tabs.getElementsByTagName("li"); // 搜尋導航標簽(ID為tabs)里的所有l(wèi)i標簽
var theLink = tabs.getElementsByTagName("a"); // 搜尋導航標簽(ID為tabs)里的所有a標簽

為什么要找出所有的li和a標簽呢?呵呵,這個是由于我這里采取的設置樣式的結構決定的(其實我也老是覺得不怎么好,不過這個思維個人比較好理解--頭疼醫(yī)頭,腳疼醫(yī)腳的方法)。看看我們上邊的CSS樣式,大家看到了,我們是用改變標簽菜單(li)的樣式來實現(xiàn)特別顯示當前標簽的。那么我這里就自然要獲取所有的li標簽,然后給他添加onclick來調用ajaxInject(ListName,tabId,tarObj,URL),從而改變標簽的樣式。看看我來實現(xiàn)這個功能的代碼吧:

for(var j=0;j<theList.length;j++){
var theTab = theList[j];
if(theTab.parentNode!=tabs) continue;

var theA = theLink[j];
// 屏蔽掉a標簽默認的處理(打開新鏈接)事件
theA.onclick = function(){
return false;
}

// 為導航TAB菜單(li)設置onclick處理方法(函數(shù))
theTab.onclick = function(){
var theClass = this.className;
if(theClass!="current" && theClass!="first"){
var objId = this.getAttribute("id").split("-")[1]; // 當前選中標簽(li)在菜單(ul)中的索引值
var tarObj = this.getAttribute("id").split("-")[0]; // 要顯示信息的目標DOM節(jié)點ID值
var theURL = tarObj + "/" + tarObj + objId + ".htm"; // 要異步加載的URL地址
ajaxInject((tarObj),objId,tarObj,theURL);
return false;
}
}
}

我們通過使用一個for循環(huán)來遍歷所有的li和a標簽(由于它們個數(shù)相同,所以索引的值相同),然后分別為它們設置onclick事件。先看我們給a標簽添加的事件的代碼:

var theA = theLink[j];
// 屏蔽掉a標簽默認的處理(打開新鏈接)事件
theA.onclick = function(){
return false;
}

一個簡單的return false,可別小看它哦,有幾個作用哦,首先a標簽是嵌套在li標簽里的,我們點li時就一定會出發(fā)a標簽的默認行為,打開鏈接的頁面。而我們ajax標簽導航就是希望不刷(打開)新頁面,在指定的DOM節(jié)點顯示信息。當然就不能讓a標簽的默認行為啟動了,而簡單的一個return false;就解決了這個問題。哦,這里還有個問題就是DOM事件的冒泡的順序,詳細的介紹大家可以在《Javascript高級編程》一書中查到。

那有些朋友會問,為什么要在里面加個a標簽呢?反正你是改變的是li的樣式,點了li,改變li的樣式,然后刷新指定DOM節(jié)點的信息不就完成了ajax標簽導航的功能(效果)了嗎?

是啊,不過我在這里要提的就是剛才提到的一個預留退路的思想,如果想上面說的那樣做了,當然是沒有什么問題,但前提是用戶的瀏覽器支持javascript腳本,或者說用戶打開了執(zhí)行腳本的權限。一旦用戶的瀏覽器不支持javascript或者出于安全原因關閉了腳本執(zhí)行功能。這個時候,當用戶點li時是沒有任何反映的。而我這里的處理就考慮到了當javascript執(zhí)行不了的情況,這時候,用戶點鏈接就可以打開我們原本要用ajax加載的內容了。

其實這里還有各個比較簡單的方法來達成我提到的相同的效果,就是對li使用onmouseover事件,想想為什么?因為只要鼠標劃過時,就觸發(fā)了ajaxInject((tarObj),objId,tarObj,theURL);改變了標簽的樣式,刷新了內容。當點擊鏈接時,就可以彈出頁面了。現(xiàn)在網(wǎng)易和雅虎中國就是這么處理的。其實我這么做主要是處于個人習慣,比較喜歡用onclick,還有就是這里有個分隔線的效果,看上去比網(wǎng)易的只用一個背景圖片酷,當然我的效果是學的雅虎(不是雅虎中國)的。不過雅虎的標簽樣式的處理方式要比我現(xiàn)在的更巧妙,下次有時間再跟大家分析下雅虎的標簽導航效果。

又扯遠了,OK,接下來我們就是要改變樣式和ajax刷新內容了。不過在這個之前,看看我做了什么準備。


<ul class="tabs" id="news">
<li class="first" id="news-0"><a href="news/news0.htm">網(wǎng)站重構</a><span></span></li>
<li id="news-1"><a href="news/news1.htm">CSS布局實錄</a><span></span></li>
<li id="news-2"><a href="news/news2.htm">海嘯的地盤</a><span></span></li>
<li id="news-3"><a href="news/news3.htm">Ajax高級編程</a><span></span></li>
</ul>

var objId = this.getAttribute("id").split("-")[1]; // 當前選中標簽(li)在菜單(ul)中的索引值
var tarObj = this.getAttribute("id").split("-")[0]; // 要顯示信息的目標DOM節(jié)點ID值
var theURL = tarObj + "/" + tarObj + objId + ".htm"; // 要異步加載的URL地址

看看我文章前面部分羅列的東西,現(xiàn)在就在這里有了回應了

id="news" - news就是我們的導航標簽的ID;
id="news-0" - news-0 通過”-“分開,我們就分別可以得到news(導航標簽ID),0(標簽[li]在導航標簽中的索引值)

好現(xiàn)在就要改變標簽的樣式了

/* ===========================================================
* 函數(shù)名稱:ajaxInject(ListName,tabId,tarObj,URL)
* 參數(shù)說明:ListName - 標簽菜單DOM節(jié)點ID
* tabId - 選中的標簽(在ListName中的)索引值
* tarObj - 要顯示返回信息的目標DOM節(jié)點ID值
* URL - 要異步處理的URL地址
* 函數(shù)功能:設置當前選中標簽(li)的樣式,
* 將返回信息寫到指定DOM節(jié)點中。
* 返 回 值:無
* 使用方法:ajaxInject((tarObj),objId,tarObj,theURL);
============================================================ */
function ajaxInject(ListName,tabId,tarObj,URL){
if(!ListName || !document.getElementsByTagName) return false;
var Tabs = ListName;
var theLi = Tabs.getElementsByTagName("li");
for(var i=0;i<theLi.length;i++){
// 設置當前選中標簽的樣式
if(i==tabId){
if(i==0){
theLi[tabId].className = "first"; // 當選中第一項的樣式
}
else{//
theLi[tabId].className = "current"; // 選中其他項的樣式
}
var msgBox = tarObj+"Cnt";
var loadstatustext="<div class='loading'><img src='img/loading.gif' alt='正在加載內容, 請稍候...' />正在加載內容, 請稍候...</div>";
(msgBox).innerHTML = loadstatustext; // 加載信息時的提示信息
var para = "?d=" + Math.random(); // URL后的參數(shù),接Math.random()(一個隨機數(shù)),目的是處理ajax的緩存問題
var myAjax = ajaxUpdater(msgBox,"get",URL,para);
}
else{// 設置其他標簽的樣式
theLi[i].className = "";
if(tabId!=0){
theLi[tabId-1].className = "off"; // 當不是第一項時,隱藏選中項的前一項的分隔標簽
}
}
}
}

這里又跟前面的

id="newsCnt" - newsCnt就是我們要寫入信息的目標DOM節(jié)點;
class="first" - first當前(第一個)標簽的樣式;

對應起來了。

for(var i=0;i<theLi.length;i++){
// 設置當前選中標簽的樣式
if(i==tabId){
if(i==0){
theLi[tabId].className = "first"; // 當選中第一項的樣式
}
else{
theLi[tabId].className = "current"; // 選中其他項的樣式
}
}
else{// 設置其他標簽的樣式
theLi[i].className = "";
if(tabId!=0){
theLi[tabId-1].className = "off"; // 當不是第一項時,隱藏選中項的前一項的分隔標簽
}
}
}

上面這段代碼就是具體改變樣式的,i==tabId比較當前標簽的索引值(作用就是確認是否是選中的標簽),相等了就給標簽設置樣式了。i==0表明第一項被選種(由于我的第一項的背景特殊的)給它加上“first”樣式,其余項被選中則加上“current”樣式。

接這就是處理分隔錢的樣式了,跟設置背景大同小意,這里要說的是我們在寫CSS的時候要把li(選中和失去焦點)的樣式設置好。還是我之前提到的,YAHOO的做得很好,我記得網(wǎng)上也有關于滑動門技術CSS寫法的介紹,大家可以看看是怎么來設置樣式的,還有這里給大家推薦個小軟件《CSS Tab Designer 2》。

恩,現(xiàn)在要刷新指定DOM節(jié)點的內容了,用一個簡單的var myAjax = ajaxUpdater(msgBox,"get",URL,para);就解決問題了。不過我們看看在把信息寫到指定DOM節(jié)點前,我做了什么:

var msgBox = tarObj+"Cnt";
var loadstatustext="<div class='loading'><img src='img/loading.gif' alt='正在加載內容, 請稍候...' />正在加載內容, 請稍候...</div>";
(msgBox).innerHTML = loadstatustext; // 加載信息時的提示信息

這里做了一個提示的處理,因為ajax是異步的加載,在獲取很長(信息量很大)的內容時,會有一個延時,如果在這個期間不給任何提示信息的話,我們要刷新的DOM節(jié)點會出現(xiàn)白白的一片,這個當然是不美觀的。所以在這之前,我們給用戶一個提示信息,說明正在加載信息會顯得更人性化些。當然,大家知道的網(wǎng)易的處理會更好些,做一個延遲的window.setTimeout效果。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 赣州市| 谷城县| 松桃| 盐城市| 高淳县| 龙井市| 高台县| 蓬安县| 个旧市| 新宾| 丽水市| 屏南县| 靖边县| 瓮安县| 防城港市| 开鲁县| 类乌齐县| 东兰县| 修武县| 新沂市| 双牌县| 海伦市| 屏东市| 方山县| 邵武市| 西华县| 壤塘县| 木兰县| 龙门县| 罗平县| 宝丰县| 新巴尔虎右旗| 乌兰察布市| 沧州市| 兴海县| 郯城县| 长寿区| 灵丘县| 永安市| 嫩江县| 武平县|