1. 程式人生 > >第10章 文檔對象模型DOM 10.3 Element類型

第10章 文檔對象模型DOM 10.3 Element類型

cas dash 區分大小寫 容易出錯 pla 代碼 html元素 des firefox

Element 類型用於表現 XML或 HTML元素,提供了對元素標簽名、子節點及特性的訪問。

要訪問元素的標簽名,可以使用 nodeName 屬性,也可以使用 tagName 屬性;這兩個屬性會返回相同的值。如下所示:

<div id="myDiv"></div>

var div = document.getElementById("myDiv");

alert(div.tagName); //"DIV"

alert(div.tagName == div.nodeName); //true

在 HTML 中,標簽名始終都以全部大寫表示;而在 XML(有時候也包括 XHTML)中,標簽名則始終會與源代碼中的保持一致。假如你不確定自己的腳本將會在 HTML 還是 XML 文檔中執行,最好是在比較之前將標簽名轉換為相同的大小寫形式,如下所示:

if (element.tagName == "div"){ //不能這樣比較,很容易出錯!

//在此執行某些操作

}

if (element.tagName.toLowerCase() == "div"){ //這樣最好(適用於任何文檔)

//在此執行某些操作

}

(可以在任何瀏覽器中通過腳本訪問 Element 類型的構造函數及原型,包括 IE8及之前版本。在 Safari 2之前版本和 Opera 8之前的版本中,不能訪問 Element 類型的構造函數。)

HTML 元素

所有 HTML 元素都由 HTMLElement 類型表示,不是直接通過這個類型,也是通過它的子類型來表示。

HTMLElement 類型直接繼承自 Element 並添加了一些屬性。 添加的這些屬性分別對應於每個HTML元素中都存在的下列標準特性:

id ,元素在文檔中的唯一標識符。

title ,有關元素的附加說明信息,一般通過工具提示條顯示出來。

lang ,元素內容的語言代碼,很少使用。

dir ,語言的方向,值為 "ltr" (left-to-right,從左至右)或 "rtl" (right-to-left,從右至左) ,也很少使用。

className , 與元素的 class 特性對應, 即為元素指定的CSS類。 沒有將這個屬性命名為 class ,是因為 class 是 ECMAScript 的保留字

上述這些屬性都可以用來取得或修改相應的特性值。

所有 HTML 元素都是由 HTMLElement 或者其更具體的子類型來表示的。下表列出了所有 HTML 元素以及與之關聯的類型(以斜體印刷的元素表示已經不推薦使用了) 。這些類型在 Opera、Safari、Chrome 和 Firefox 中都可以通過 JavaScript 訪問。

取得特性

每個元素都有一或多個特性,這些特性的用途是給出相應元素或其內容的附加信息。操作特性的DOM 方法主要有三個,分別是 getAttribute() 、 setAttribute() 和 removeAttribute() 。這三個方法可以針對任何特性使用, 包括那些以 HTMLElement 類型屬性的形式定義的特性。

如下所示:

var div = document.getElementById("myDiv");

alert(div.getAttribute("id")); //"myDiv"

alert(div.getAttribute("class")); //"bd"

alert(div.getAttribute("title")); //"Body text"

alert(div.getAttribute("lang")); //"en"

alert(div.getAttribute("dir")); //"ltr"

傳遞給 getAttribute() 的特性名與實際的特性名相同,如果給定名稱的特性不存在, getAttribute() 返回 null 。

通過 getAttribute() 方法還可以取得自定義特性,如:

<div id="myDiv" myAttribute="hello!"></div>

var value = div.getAttribute("myAttribute");

不過,特性的名稱是不區分大小寫的,另外,根據HTML5規範,自定義特性應該加上 data- 前綴以便驗證。

任何元素的所有特性,也都可以通過 DOM元素本身的屬性來訪問。當然, HTMLElement 也會有 5個屬性與相應的特性一一對應。不過,只有公認的(非自定義的)特性才會以屬性的形式添加到 DOM對象中。以下面的元素為例:

<div id="myDiv" align="left" my_special_attribute="hello!"></div>

因為 id 和 align 在 HTML 中是 <div> 的公認特性,因此該元素的 DOM對象中也將存在對應的屬性。不過,自定義特性 my_special_attribute 在 Safari、Opera、Chrome 及 Firefox 中是不存在的;但 IE 卻會為自定義特性也創建屬性,因此:

alert(div.id); //"myDiv"

alert(div.my_special_attribute); //undefined(IE 除外)

alert(div.align); //"left"

有兩類特殊的特性, 它們雖然有對應的屬性名, 但屬性的值與通過 getAttribute() 返回的值並不相同。

第一類特性就是 style ,用於通過 CSS 為元素指定樣式。在通過 getAttribute() 訪問時,返回的 style 特性值中包含的是 CSS 文本,而通過屬性來訪問它則會返回一個對象。

第二類與眾不同的特性是 onclick 這樣的事件處理程序。如果通過 getAttribute() 訪問,則會返回相應代碼的字符串。而在訪問onclick 屬性時,則會返回一個 JavaScript 函數

由於這些差別,在通過 JavaScript 以編程方式操作 DOM 時,開發人員經常不使用getAttribute() ,而是只使用對象的屬性。只有在取得自定義特性值的情況下,才會使用 getAttribute() 方法。

設置特性

與 getAttribute() 對應的方法是 setAttribute() ,這個方法接受兩個參數:要設置的特性名和值。 如果特性已經存在, setAttribute() 會以指定的值替換現有的值; 如果特性不存在, setAttribute()則創建該屬性並設置相應的值。

如:

div.setAttribute("id", "someOtherId");

div.setAttribute("class", "ft");

通過 setAttribute() 方法既可以操作 HTML 特性也可以操作自定義特性。通過這個方法設置的特性名會被統一轉換為小寫形式,即 "ID" 最終會變成 "id" 。

因為所有特性都是屬性,所以直接給屬性賦值可以設置特性的值,如下所示

div.id = "someOtherId";

div.align = "left";

不過,像下面這樣為 DOM 元素添加一個自定義的屬性,該屬性不會自動成為元素的特性。

div.mycolor = "red";

alert(div.getAttribute("mycolor")); //null(IE 除外)

最後一個方法是 removeAttribute() ,這個方法用於徹底刪除元素的特性。調用這個方法不僅會清除特性的值,而且也會從元素中完全刪除特性。

attributes 屬性

Element 類型是使用 attributes 屬性的唯一一個 DOM節點類型。

attributes 屬性中包含一個NamedNodeMap,與NodeList類似,也是一個“動態”的集合。

元素的每一個特性都由一個 Attr 節點表示,每個節點都保存在 NamedNodeMap 對象中。

NamedNodeMap 對象擁有下列方法。

q getNamedItem(name) :返回 nodeName 屬性等於 name 的節點;

q removeNamedItem(name) :從列表中移除 nodeName 屬性等於 name 的節點;

q setNamedItem(node) :向列表中添加節點,以節點的 nodeName 屬性為索引;

q item(pos) :返回位於數字 pos 位置處的節點。

attributes 屬性中包含一系列節點, 每個節點的 nodeName 就是特性的名稱, 而節點的 nodeValue

就是特性的值。

要取得元素的 id 特性,可以使用以下代碼:

var id = element.attributes.getNamedItem("id").nodeValue;

或者:var id = element.attributes["id"].nodeValue;

同樣可以使用這種語法來設置特性的值:

element.attributes["id"].nodeValue = "someOtherId";

調用 removeNamedItem() 方法與在元素上調用 removeAttribute() 方法的效果相同——直接刪除具有給定名稱的特性。

removeNamedItem() 返回表示被刪除特性的 Attr 節點

var oldAttr = element.attributes.removeNamedItem("id");

setNamedItem() 是一個很不常用的方法,通過這個方法可以為元素添加一個新特性,為此需要為它傳入一個特性節點。

在需要將 DOM結構序列化為 XML 或 HTML 字符串時,多數都會涉及遍歷元素特性。以下代碼展示了如何叠代元素的每一個特性,然後將它們構造成 name="value" name="value" 這樣的字符串格式。

function outputAttributes(element){

var pairs = new Array(),

attrName,

attrValue,

i,

len;

for (i=0, len=element.attributes.length; i < len; i++){

attrName = element.attributes[i].nodeName;

attrValue = element.attributes[i].nodeValue;

pairs.push(attrName + "=\"" + attrValue + "\"");

}

return pairs.join(" ");

}

這個函數使用了一個數組來保存名值對,最後再以空格為分隔符將它們拼接起來(這是序列化長字符串時的一種常用技巧) 。通過 attributes.length 屬性, for 循環會遍歷每個特性,將特性的名稱和值輸出為字符串

創建元素

使用 document.createElement() 方法可以創建新元素。

這個方法只接受一個參數,即要創建元素的標簽名。這個標簽名在 HTML 文檔中不區分大小寫,而在 XML(包括 XHTML)文檔中,則是區分大小寫的。

在使用 createElement() 方法創建新元素的同時,也為新元素設置了 ownerDocuemnt 屬性。

要把新元素添加到文檔樹,可以使用 appendChild() 、 insertBefore() 或 replaceChild() 方法。

例如:

var div = document.createElement("div");

div.id = "myNewDiv";

div.className = "box";

document.body.appendChild(div);

在IE中可以以另一種方式使用 createElement(),即為這個方法傳入完整的元素標簽,也可以包含屬性:

var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >");

元素的子節點

不同瀏覽器在看待這些節點方面存在顯著的不同,以下面的代碼為例:

<ul id="myList">

<li>Item 1</li>

<li>Item 2</li>

<li>Item 3</li>

</ul>

如果是 IE 來解析這些代碼,那麽 <ul> 元素會有 3 個子節點,分別是 3 個 <li> 元素。但如果是在其他瀏覽器中, <ul> 元素都會有 7 個元素,包括 3 個 <li> 元素和 4 個文本節點

如果像下面這樣將元素間的空白符刪除,那麽所有瀏覽器都會返回相同數目的子節點:

<ul id="myList"><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>

瀏覽器間的這一差別。這意味著在執行某項操作以前,通常都要先檢查一下 nodeTpye 屬性,

如下所示:

for (var i=0, len=element.childNodes.length; i < len; i++){

if (element.childNodes[i].nodeType == 1){

//執行某些操作

}

}

這個例子會循環遍歷特定元素的每一個子節點,然後只在子節點的 nodeType 等於 1(表示是元素節點)的情況下,才會執行某些操作。

要想取得前面<ul> 元素中包含的所有 <li> 元素,可以如下:

var ul = document.getElementById("myList");

var items = ul.getElementsByTagName("li");

要註意的是,這裏 <ul> 的後代中只包含直接子元素。不過,如果它包含更多層次的後代元素,那

麽各個層次中包含的 <li> 元素也都會返回。

第10章 文檔對象模型DOM 10.3 Element類型