例如處理事件的時(shí)候,有時(shí)候需要知道當(dāng)前點(diǎn)擊的是第幾個(gè)子節(jié)點(diǎn),而HTML DOM本身并沒有直接提供相應(yīng)的屬性,需要自己來計(jì)算。
從一個(gè)索引序號(hào),很容易得到該索引對應(yīng)的子節(jié)點(diǎn)或者子元素,直接用parentNode.childNodes[index] 或 parentNode.children[index] 就行。
但反過來,已知一個(gè)節(jié)點(diǎn)或元素對象,要知道它的索引序號(hào)則沒有那么直接了。
一些特殊的元素,HTML DOM有對應(yīng)的屬性表示其索引序號(hào),主要是表格的TD 和 TR 元素。
表格單元格TD元素有 cellIndex 屬性。
表格行TR元素有rowIndex屬性。
如果你的處理目標(biāo)剛好就是表格,則優(yōu)先使用這兩個(gè)屬性。
但一般的節(jié)點(diǎn)或元素并沒有 childNodeIndex 或者 childElementIndex 之類的屬性。
解決方案主要分為兩類:
一、預(yù)先計(jì)算并緩存節(jié)點(diǎn)的索引號(hào)(可以存在節(jié)點(diǎn)屬性或者js變量中)。
二、實(shí)時(shí)計(jì)算,需要遍歷部分節(jié)點(diǎn)。
應(yīng)用中,可根據(jù)不同的實(shí)際情況,選用上述兩類方案之一。
適用方案一的情形:
當(dāng)DOM結(jié)構(gòu)不會(huì)變化,并且需要頻繁的獲取個(gè)別節(jié)點(diǎn)的索引,可采用方案一。
優(yōu)點(diǎn)是后續(xù)讀取快,缺點(diǎn)是初始化需要開銷,DOM結(jié)構(gòu)變化后需要重新初始化。
適用方案二的情形:
DOM結(jié)構(gòu)可能會(huì)變化,并且不是特別頻繁的獲取個(gè)別節(jié)點(diǎn)的索引,可采用方案二。
優(yōu)點(diǎn)是不受DOM結(jié)構(gòu)變化的影響,不會(huì)污染DOM結(jié)構(gòu),沒有初始化開銷。缺點(diǎn)是不適合高頻率調(diào)用。
一般而言,采用方案二是更好的,因?yàn)橥ǔOM樹規(guī)模是比較有限的,一輪的循環(huán)并不會(huì)導(dǎo)致顯著降低整體性能,而其優(yōu)點(diǎn)則是顯著的。
對于IE瀏覽器,則有更直接的方法。
從IE4到IE11,都有sourceIndex屬性,這個(gè)屬性表示了元素在DOM樹的順序,比較元素和父元素的sourceIndex的差值就很容易知道元素是第幾個(gè)子元素了。
我寫了一段函數(shù)來區(qū)分處理,在IE下采用sourceIndex高效判斷,非IE則采用一般遍歷。
復(fù)制代碼 代碼如下:
function getChildrenIndex(ele){
//IE is simplest and fastest
if(ele.sourceIndex){
return ele.sourceIndex - ele.parentNode.sourceIndex - 1;
}
//other browsers
var i=0;
while(ele = ele.previousElementSibling){
i++;
}
return i;
}
復(fù)制代碼 代碼如下:
function getNodeIndex(node){
var i=0;
while(ele = ele.previousSibling){
i++;
}
return i;
}
新聞熱點(diǎn)
疑難解答
圖片精選