第10章 DOM
1. 節(jié)點(diǎn)層次
文檔節(jié)點(diǎn)
是每個(gè)文檔的根節(jié)點(diǎn)昆庇。
(1) Node 類型
- 每個(gè)節(jié)點(diǎn)都有一個(gè)
nodeType
屬性,用于表明節(jié)點(diǎn)的類型。 - 節(jié)點(diǎn)類型由在 Node 類型中定義的下列 12 個(gè)數(shù)值常量來表示,任何節(jié)點(diǎn)類型必居其一:
(1) Node.ELEMENT_NODE(1);
(2) Node.ATTRIBUTE_NODE(2);
(3) Node.TEXT_NODE(3);
(4) Node.CDATA_SECTION_NODE(4);
(5) Node.ENTITY_REFERENCE_NODE(5);
(6) Node.ENTITY_NODE(6);
(7) Node.PROCESSING_INSTRUCTION_NODE(7);
(8) Node.COMMENT_NODE(8);
(9) Node.DOCUMENT_NODE(9);
(10) Node.DOCUMENT_TYPE_NODE(10);
(11) Node.DOCUMENT_FRAGMENT_NODE(11);
(12) Node.NOTATION_NODE(12)吼旧。
- IE 沒有公開 Node 類型的構(gòu)造函數(shù),為了確被宋跨瀏覽器兼容,最好還是將
nodeType 屬性與數(shù)字值
進(jìn)行比較。
* nodeName
和 nodeValue
屬性
* 節(jié)點(diǎn)關(guān)系
- 每個(gè)節(jié)點(diǎn)都有一個(gè)
childNodes
屬性,其中保存著一個(gè) NodeList 對象圈暗。
- 每個(gè)節(jié)點(diǎn)都有一個(gè)
- NodeList 是一種類數(shù)組 對象,用于保存一組有序的節(jié)點(diǎn),可以通過位置來訪問這些節(jié)點(diǎn)掂为。
- 雖然可以通過方括號(hào)語法來 訪問 NodeList 的值,而且這個(gè)對象也有
length 屬性
,但它并不是 Array 的實(shí)例
。- NodeList 對象的獨(dú)特之處在于,它實(shí)際上是
基于 DOM 結(jié)構(gòu)動(dòng)態(tài)執(zhí)行查詢的結(jié)果
,因此 DOM 結(jié)構(gòu)的變化能夠自動(dòng)反映在 NodeList 對象中员串。
- 訪問保存在 NodeList 中的節(jié)點(diǎn)——可以通過方括號(hào),也可以使用 item() 方法勇哗。
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
- 將 NodeList 對象轉(zhuǎn)換為數(shù)組
function convertToArray(nodes){
var array = null;
try {
array = Array.prototype.slice.call(nodes, 0); //針對非 IE 瀏覽器
} catch (ex) {
array = new Array();
for (var i=0, len=nodes.length; i < len; i++){
array.push(nodes[i]);
}
}
return array;
}
- 每個(gè)節(jié)點(diǎn)都有一個(gè)
parentNode
屬性,該屬性指向文檔樹中的父節(jié)點(diǎn)。
- 每個(gè)節(jié)點(diǎn)都有一個(gè)
包含在 childNodes 列表中 的所有節(jié)點(diǎn)都具有相同的父節(jié)點(diǎn),因此它們的 parentNode 屬性都指向同一個(gè)節(jié)點(diǎn)寸齐。
- 包含在 childNodes 列表中的每個(gè)節(jié)點(diǎn)相互之間都是同胞節(jié)點(diǎn)欲诺。通過使用列表中每個(gè)節(jié)點(diǎn)的
previousSibling
和nextSibling
屬性,可以訪問同一列表中的其他節(jié)點(diǎn)。
- 包含在 childNodes 列表中的每個(gè)節(jié)點(diǎn)相互之間都是同胞節(jié)點(diǎn)欲诺。通過使用列表中每個(gè)節(jié)點(diǎn)的
- 父節(jié)點(diǎn)的
firstChild
和lastChild
屬性分別指向其 childNodes 列表中的第一個(gè)和最后一個(gè)節(jié)點(diǎn)渺鹦。
節(jié)點(diǎn)關(guān)系
- 父節(jié)點(diǎn)的
5.
hasChildNodes()方法
在節(jié)點(diǎn)包含一或多個(gè)子節(jié)點(diǎn)的情況下返回 true扰法。-
ownerDocument屬性
指向表示整個(gè)文檔的文檔節(jié)點(diǎn)。
-
* 操作節(jié)點(diǎn)
-
appendChild()
方法:用于向 childNodes 列表的末尾添加一個(gè)節(jié)點(diǎn)毅厚。
如果傳入到 appendChild()中的節(jié)點(diǎn)已經(jīng)是文檔的一部分了,那結(jié)果就是將該節(jié)點(diǎn)從原來的位置轉(zhuǎn)移到新位置塞颁。
//someNode 有多個(gè)子節(jié)點(diǎn)
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild); //false
alert(returnedNode == someNode.lastChild); //true
-
insertBefore()
方法:接受兩個(gè)參數(shù):要插入的節(jié)點(diǎn)
和作為參照的節(jié)點(diǎn)
。插入節(jié)點(diǎn)后,被插 入的節(jié)點(diǎn)會(huì)變成參照節(jié)點(diǎn)的前一個(gè)同胞節(jié)點(diǎn)(previousSibling),同時(shí)被方法返回吸耿。
如果參照節(jié)點(diǎn)是 null,則 insertBefore()與 appendChild()執(zhí)行相同的操作
祠锣。
3.replaceChild()
方法:接受的兩個(gè)參數(shù)是:要插入的節(jié)點(diǎn)
和要替換的節(jié)點(diǎn)
。要替換的節(jié)點(diǎn)將由這個(gè) 方法返回并從文檔樹中被移除,同時(shí)由要插入的節(jié)點(diǎn)占據(jù)其位置咽安。
4.removeChild()
方法:接受一個(gè)參數(shù),即要移除 的節(jié)點(diǎn)伴网。被移除的節(jié)點(diǎn)將成為方法的返回值。
* 其他方法
-
cloneNode()
方法:用于創(chuàng)建調(diào)用這個(gè)方法的節(jié)點(diǎn)的一個(gè)完全相同的副本妆棒。接受一個(gè)布爾值參數(shù),表示是否執(zhí)行深復(fù)制澡腾。在參數(shù)為 true 的情況下,執(zhí)行深復(fù)制,也就是復(fù)制節(jié)點(diǎn)及其整個(gè)子節(jié)點(diǎn)樹;在參數(shù)為 false 的情況下,執(zhí)行淺復(fù)制, 即只復(fù)制節(jié)點(diǎn)本身。
2.normalize()
方法:由于解析器的實(shí)現(xiàn)或 DOM 操作等原因,可能會(huì)出現(xiàn)文本節(jié)點(diǎn)不包含文本,或者接連出現(xiàn)兩個(gè)文本節(jié)點(diǎn) 的情況糕珊。當(dāng)在某個(gè)節(jié)點(diǎn)上調(diào)用這個(gè)方法時(shí),就會(huì)在該節(jié)點(diǎn)的后代節(jié)點(diǎn)中查找上述兩種情況蛋铆。如果找到了空文本節(jié)點(diǎn),則刪除它;如果找到相鄰的文本節(jié)點(diǎn),則將它們合并為一個(gè)文本節(jié)點(diǎn)。
(2) Document類型
- JavaScript 通過 Document 類型表示文檔放接。
- 在瀏覽器中,document 對象是 HTMLDocument(繼承自 Document 類型)的一個(gè)實(shí)例,表示整個(gè) HTML 頁面刺啦。
- document 對象是 window 對象的一個(gè) 屬性,因此可以將其作為全局對象來訪問。
Document 節(jié)點(diǎn)具有下列特征:
(1) nodeType 的值為 9;
(2) nodeName 的值為"#document";
(3) nodeValue 的值為 null;
(4) parentNode 的值為 null;
(5) ownerDocument 的值為 null;
(6) 其子節(jié)點(diǎn)可能是一個(gè) DocumentType(最多一個(gè))纠脾、Element(最多一個(gè))玛瘸、ProcessingInstruction
或 Comment蜕青。
* 文檔的子節(jié)點(diǎn)
Document 節(jié)點(diǎn)的子節(jié)點(diǎn)可以是DocumentType、Element糊渊、ProcessingInstruction 或 Comment右核。
1.兩個(gè)內(nèi)置的訪問其子節(jié)點(diǎn)的快捷方式
:
documentElement 屬性
,該屬性始終指向 HTML 頁面中的<html>元素。- 通過 childNodes 列表訪問文檔元素渺绒。
-
document.body
,body 屬性,直接指向<body>元素贺喝。
3.Document 另一個(gè)可能的子節(jié)點(diǎn)是 DocumentType。通常將<!DOCTYPE>標(biāo)簽看成一個(gè)與文檔其他 部分不同的實(shí)體,可以通過 doctype 屬性(在瀏覽器中是 document.doctype
)來訪問它的信息宗兼。
* 文檔信息
title屬性
:可以取得當(dāng)前頁面的標(biāo)題,也可以修改當(dāng)前頁面的標(biāo)題并反映在瀏覽器的標(biāo)題欄中躏鱼。(document.title
)URL屬性
:包含頁面完整的 URL(即地址欄中顯示的 URL)。(document.URL
)domain 屬性
:只包含頁面的域名殷绍。(document.domain)referrer 屬性
: 保存著鏈接到當(dāng)前頁面的那個(gè)頁面的 URL染苛。在沒有來源頁面的情況下,referrer 屬性中可能 會(huì)包含空字符串。(document.referrer)
(1) 只有
domain 是可以設(shè)置
的。但由于安全方面的限制,也并非可以給 domain 設(shè) 置任何值。如果 URL 中包含一個(gè)子域名,例如 p2p.wrox.com,那么就只能將 domain 設(shè)置為"wrox.com" (URL 中包含"www",如 www.wrox.com 時(shí),也是如此)断序。不能將這個(gè)屬性設(shè)置為 URL 中不包含的域。
//假設(shè)頁面來自 p2p.wrox.com 域
document.domain = "wrox.com"; // 成功
document.domain = "nczonline.net"; // 出錯(cuò)!
(2) 瀏覽器對 domain 屬性還有一個(gè)限制,即如果域名一開始是“松散的”(loose),那么不能將它再設(shè) 置為“緊繃的”(tight)畔师。換句話說,在將 document.domain 設(shè)置為"wrox.com"之后,就不能再將其 設(shè)置回"p2p.wrox.com",否則將會(huì)導(dǎo)致錯(cuò)誤。
//假設(shè)頁面來自于 p2p.wrox.com 域
document.domain = "wrox.com"; //松散的(成功)
document.domain = "p2p.wrox.com"; //緊繃的(出錯(cuò)!)
*查找元素
getElementById()
(1) 接收一個(gè)參數(shù):要取得的元素的 ID牧牢。如果找到相應(yīng)的元素則返回該元素,如果不存在帶有相應(yīng) ID 的元素,則返回 null看锉。
(2) 如果頁面中多個(gè)元素的 ID 值相同,getElementById()只返回文檔中第一次出現(xiàn)的元素
。
(3) ID 必須與頁面中元素的 id 特性(attribute)嚴(yán)格匹配
,包括大小寫
-
getElementsByTagName()
:
(1) 接受一個(gè)參數(shù),即要取得元素的標(biāo)簽名,而返回的是包含零或多個(gè)元素的 NodeList结执。
(2) 在 HTML 文檔中,這個(gè)方法會(huì)返回一 個(gè)HTMLCollection 對象
,作為一個(gè)“動(dòng)態(tài)”集合,該對象與 NodeList 非常類似度陆。
(3) 與 NodeList 對象類似,可以 使用方括號(hào)
語法或item()方法
來訪問 HTMLCollection 對象中的項(xiàng)艾凯。而這個(gè)對象中元素的數(shù)量則可以 通過其length 屬性
取得献幔。
var images = document.getElementsByTagName("img");
alert(images.length);//輸出圖像的數(shù)量
alert(images[0].src); //輸出第一個(gè)圖像元素的 src 特性
alert(images.item(0).src);//輸出第一個(gè)圖像元素的 src 特性
(4) HTMLCollection 對象還有一個(gè)方法,叫做
namedItem()
,使用這個(gè)方法可以通過元素的 name 特性取得集合中的項(xiàng)。
<img src="myimage.gif" name="myImage">
var myImage = images.namedItem("myImage");
(5) HTMLCollection 還支持按名稱訪問項(xiàng),對命名的項(xiàng)也可以使用方括號(hào)語法來訪問趾诗。
var myImage = images["myImage"];
對 HTMLCollection 而言,我們可以向方括號(hào)中傳入數(shù)值或字符串形式的索引值蜡感。在后臺(tái),對數(shù) 值索引就會(huì)調(diào)用 item(),而對字符串索引就會(huì)調(diào)用 namedItem()。
(6) 要想取得文檔中的所有元素,可以向 getElementsByTagName()中傳入"*"恃泪。
3.getElementsByName()
:
(1) 只有 HTMLDocument 類型才有的方法,這個(gè)方法會(huì)返回帶有給定 name 特性的所有元素郑兴。
* 特殊集合
(1)
document.anchors
,包含文檔中所有帶 name 特性的<a>元素;
(2)document.applets
,包含文檔中所有的<applet>元素,因?yàn)椴辉偻扑]使用<applet>元素,所以這個(gè)集合已經(jīng)不建議使用了;
(3)document.forms
,包含文檔中所有的<form>元素,與 document.getElementsByTagName("form")得到的結(jié)果相同;
(4)document.images
,包含文檔中所有的<img>元素,與 document.getElementsByTagName("img")得到的結(jié)果相同;
(5)document.links
,包含文檔中所有帶 href 特性的<a>元素。
* DOM 一致性檢測
由于 DOM 分為多個(gè)級(jí)別,也包含多個(gè)部分,因此檢測瀏覽器實(shí)現(xiàn)了 DOM 的哪些部分就十分必要 了贝乎。document.implementation 屬性
就是為此提供相應(yīng)信息和功能的對象,與瀏覽器對 DOM 的實(shí)現(xiàn)直接對應(yīng)情连。
(1) DOM1 級(jí)只為 document.implementation 規(guī)定了一個(gè)方法,即
hasFeature()
。這個(gè)方 法接受兩個(gè)參數(shù):要檢測的 DOM 功能的名稱及版本號(hào)览效。如果瀏覽器支持給定名稱和版本的功能,則該方法返回 true却舀。
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
* 文檔寫入
write()
和writeln()
方法都接受一個(gè)字符串參數(shù),即要寫入到輸出流中的文本虫几。write()會(huì)原樣寫入,而 writeln()則會(huì) 在字符串的末尾添加一個(gè)換行符(\n)。
(1) 在頁面被加載的過程中,可以使用這兩個(gè)方法向頁面中動(dòng)態(tài)地加入內(nèi)容挽拔。
<html>
<head>
<title>document.write() Example</title>
</head>
<body>
<p>The current date and time is:
<script type="text/javascript">
document.write("<strong>" + (new Date()).toString() +
"</strong>"); </script>
</p>
</body>
</html>
不能直接包含字符串"</script>",因?yàn)檫@會(huì)導(dǎo)致該 字符串被解釋為腳本塊的結(jié)束,它后面的代碼將無法執(zhí)行辆脸。需加入轉(zhuǎn)義字符\即可
(2) 如果在文檔加載結(jié)束后再調(diào)用 document.write(),那么輸出的內(nèi)容將會(huì)重寫整個(gè)頁面。
<html>
<head>
<title>document.write() Example 4</title>
</head>
<body>
<p>This is some content that you won't get to see
because it will be overwritten.</p>
<script type="text/javascript">
window.onload = function(){
document.write("Hello world!");
};
</script>
</body>
</html>
方法
open()
和close()
分別用于打開和關(guān)閉網(wǎng)頁的輸出流螃诅。如果是在頁面加載期間使用 write()或 writeln()方法,則不需要用到這兩個(gè)方法啡氢。
(3) Element類型
Element 類型用于表現(xiàn)XML或HTML 元素,提供了對元素標(biāo)簽名、子節(jié)點(diǎn)及特性的訪問术裸。
Element 節(jié)點(diǎn)具有以下特征:
(1) nodeType 的值為 1;
(2) nodeName 的值為元素的標(biāo)簽名;
(3) nodeValue 的值為 null;
(4) parentNode 可能是 Document 或 Element;
(5) 其子節(jié)點(diǎn)可能是 Element倘是、Text、Comment穗椅、ProcessingInstruction辨绊、CDATASection 或EntityReference。
- 要訪問元素的標(biāo)簽名,可以使用
nodeName
屬性,也可以使用tagName
屬性; - 在 HTML 中,標(biāo)簽名始終都以全部大寫表示,div.tagName 實(shí)際上輸出的是 "DIV"而非"div"匹表。
*HTML元素
- 所有 HTML 元素都由
HTMLElement
類型表示,不是直接通過這個(gè)類型,也是通過它的子類型來表示门坷。 - HTMLElement 類型直接繼承自 Element 并添加了一些屬性。添加的這些屬性分別對應(yīng)于每個(gè) HTML 元素中都存在的下列標(biāo)準(zhǔn)特性袍镀。
(1) id,元素在文檔中的唯一標(biāo)識(shí)符默蚌。
(2) title,有關(guān)元素的附加說明信息,一般通過工具提示條顯示出來。
(3) lang,元素內(nèi)容的語言代碼,很少使用苇羡。
(4) dir,語言的方向,值為"ltr"(left-to-right,從左至右)或"rtl"(right-to-left,從右至左),
也很少使用绸吸。
(5) className,與元素的 class 特性對應(yīng),即為元素指定的 CSS 類。
<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr">
</div>
var div = document.getElementById("myDiv");
alert(div.id);//"myDiv""
alert(div.className);//"bd"
alert(div.title);//"Body text"
alert(div.lang);//"en"
alert(div.dir);//"ltr"
* 取得特性
getAttribute()
方法:
- 通過 getAttribute()方法也可以
取得自定義特性
(即標(biāo)準(zhǔn) HTML 語言中沒有的特性)的值设江。
2.特性的名稱是不區(qū)分大小寫
的,即"ID"和"id"代表的都是同一個(gè)特性锦茁。
任何元素的所有特性,也都可以通過 DOM 元素本身的屬性來訪問。只有公認(rèn)的(非自定義的)特性才會(huì)以屬性的形式添加到 DOM 對象中叉存。
兩類特殊的特性屬性的值與通過 getAttribute()返回的值不相同:
(1) 第一類特性就是
style
,用于通過 CSS 為元素指定樣式码俩。在通過 getAttribute()訪問時(shí),返 回的 style 特性值中包含的是 CSS 文本,而通過屬性來訪問它則會(huì)返回一個(gè)對象。
(2) 第二類特性是onclick 這樣的事件處理程序
歼捏。當(dāng)在元素上使用時(shí),onclick 特性中包 含的是 JavaScript 代碼,如果通過 getAttribute()訪問,則會(huì)返回相應(yīng)代碼的字符串稿存。而在訪問 onclick 屬性時(shí),則會(huì)返回一個(gè) JavaScript 函數(shù)(如果未在元素中指定相應(yīng)特性,則返回 null)。
* 設(shè)置特性
setAttribute()
方法:
- 這個(gè)方法
接受兩個(gè)參數(shù)
:要設(shè)置的特性名和值瞳秽。如果特性已經(jīng)存在,setAttribute()會(huì)以指定的值替換現(xiàn)有的值;如果特性不存在,setAttribute() 則創(chuàng)建該屬性并設(shè)置相應(yīng)的值瓣履。 - 通過這個(gè)方法設(shè)置的 特性名會(huì)被統(tǒng)一轉(zhuǎn)換為
小寫形式
,即"ID"最終會(huì)變成"id"。
(1) 因?yàn)樗刑匦远际菍傩?所以直接給屬性賦值可以設(shè)置特性的值练俐。
(2) 為 DOM 元素添加一個(gè)自定義的屬性,該屬性不會(huì)自動(dòng)成為元素的特性袖迎。
removeAttribute()
方法:
這個(gè)方法用于徹底刪除元素的特性
。調(diào)用這個(gè)方法不僅會(huì)清除特性的值,而且也會(huì)從元素中完全刪除特性。
*attributes 屬性
1.Element 類型是使用 attributes 屬性的唯一一個(gè) DOM 節(jié)點(diǎn)類型燕锥。
2.attributes 屬性中包含一個(gè)NamedNodeMap,與 NodeList 類似,也是一個(gè)“動(dòng)態(tài)”的集合浴韭。元素的每一個(gè)特性都由一個(gè) Attr 節(jié) 點(diǎn)表示,每個(gè)節(jié)點(diǎn)都保存在 NamedNodeMap 對象中。
NamedNodeMap
對象擁有下列方法:
(1) getNamedItem(name):返回 nodeName 屬性等于 name 的節(jié)點(diǎn);
(2) removeNamedItem(name):從列表中移除 nodeName 屬性等于 name 的節(jié)點(diǎn);
(3) setNamedItem(node):向列表中添加節(jié)點(diǎn),以節(jié)點(diǎn)的 nodeName 屬性為索引;
(4) item(pos):返回位于數(shù)字 pos 位置處的節(jié)點(diǎn)脯宿。
- attributes 屬性中包含一系列節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)的
nodeName 就是特性的名稱
,而節(jié)點(diǎn)的nodeValue 就是特性的值
念颈。
var id = element.attributes.getNamedItem("id").nodeValue;
//簡寫方式
var id = element.attributes["id"].nodeValue;
//設(shè)置新值
element.attributes["id"].nodeValue = "someOtherId";
調(diào)用
removeNamedItem()方法
與在元素上調(diào)用 removeAttribute()方法的效果相同——直接刪 除具有給定名稱的特性。兩個(gè)方法間唯一的區(qū)別
,即 removeNamedItem()返回表示 被刪除特性的 Attr 節(jié)點(diǎn)连霉。針對 attributes 對象中的特性,不同瀏覽器返回的
順序不同
榴芳。這些特性在 XML 或 HTML 代 碼中出現(xiàn)的先后順序,不一定與它們出現(xiàn)在 attributes 對象中的順序一致。IE7 及更早的版本會(huì)
返回 HTML 元素中所有可能的特性
,包括沒有指定的特性跺撼。換句話說,返回 100 多個(gè)特性的情況會(huì)很常見窟感。
每個(gè)特 性節(jié)點(diǎn)都有一個(gè)名為
specified 的屬性
,這個(gè)屬性的值如果為 true,則意味著要么是在 HTML 中指定了相應(yīng)特性,要么是通過 setAttribute()方法設(shè)置了該特性。在 IE 中,所有未設(shè)置過的特性的該 屬性值都為 false,而在其他瀏覽器中根本不會(huì)為這類特性生成對應(yīng)的特性節(jié)點(diǎn)(因此,在這些瀏覽器 中,任何特性節(jié)點(diǎn)的 specified 值始終為 true)歉井。
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;
if (element.attributes[i].specified) {
pairs.push(attrName + "=\"" + attrValue + "\"");
}
}
return pairs.join(" ");
}
* 創(chuàng)建元素
document.createElement()
方法可以創(chuàng)建新元素柿祈。
這個(gè)方法只
接受一個(gè)參數(shù)
,即要?jiǎng)?chuàng)建元素的標(biāo)簽名。這個(gè)標(biāo)簽名在
HTML 文檔中不區(qū)分大小寫
,而在 XML(包括 XHTML)文檔中,則是區(qū) 分大小寫的哩至。在
IE 中
可以以另一種方式使用 createElement(),即為這個(gè)方法傳入完整的元素標(biāo)簽,也可以包含屬性躏嚎。
var div = document.createElement("<div id=\"myNewDiv\"
class=\"box\"></div >");
*元素的子節(jié)點(diǎn)
元素的 childNodes 屬性中包含了它的所有子節(jié)點(diǎn),這些子節(jié)點(diǎn)有可能是元素、文本節(jié)點(diǎn)菩貌、注釋或處理指令卢佣。
不同瀏覽器在看待這些節(jié)點(diǎn)方面存在顯著的不同,返回的子節(jié)點(diǎn)不相同箭阶。
如果需要通過 childNodes 屬性遍歷子節(jié)點(diǎn)虚茶,要先檢查 一下 nodeTpye 屬性。
for (var i=0, len=element.childNodes.length; i < len; i++){
if (element.childNodes[i].nodeType == 1){ 12
//執(zhí)行某些操作 }
}
- 元素也支持
getElementsByTagName()
方法仇参。在通過元素調(diào)用這個(gè)方法時(shí),除了搜索起點(diǎn)是當(dāng)前元素之外,其他 方面都跟通過 document 調(diào)用這個(gè)方法相同,因此結(jié)果只會(huì)返回當(dāng)前元素的后代嘹叫。
var ul = document.getElementById("myList");
var items = ul.getElementsByTagName("li");
(4) Text 類型
-
文本節(jié)點(diǎn)
由 Text 類型表示,包含的是可以照字面解釋的純文本內(nèi)容。 - 純文本中可以包含
轉(zhuǎn)義后的 HTML 字符
,但不能包含 HTML 代碼诈乒。
Text 節(jié)點(diǎn)具有以下特征
:
(1) nodeType 的值為 3;
(2) nodeName 的值為"#text";
(3) nodeValue 的值為節(jié)點(diǎn)所包含的文本; ? parentNode 是一個(gè) Element;
(4) 不支持(沒有)子節(jié)點(diǎn)罩扇。
- 通過
nodeValue 屬性
或data 屬性
訪問 Text 節(jié)點(diǎn)中包含的文本,這兩個(gè)屬性中包含的值相同。對 nodeValue 的修改也會(huì)通過 data 反映出來,反之亦然抓谴。
操作節(jié)點(diǎn)中文本的方法
:
(1) appendData(text):將 text 添加到節(jié)點(diǎn)的末尾暮蹂。
(2) deleteData(offset, count):從 offset 指定的位置開始刪除 count 個(gè)字符寞缝。
(3) insertData(offset, text):在 offset 指定的位置插入 text癌压。
(4) replaceData(offset, count, text):用 text 替換從 offset 指定的位置開始到 offset+count 為止處的文本。
(5) splitText(offset):從 offset 指定的位置將當(dāng)前文本節(jié)點(diǎn)分成兩個(gè)文本節(jié)點(diǎn)荆陆。
(6) substringData(offset, count):提取從 offset 指定的位置開始到 offset+count 為止
處的字符串滩届。
文本節(jié)點(diǎn)還有一個(gè)
length 屬性
,保存著節(jié)點(diǎn)中字符的數(shù)目。而且,nodeValue.length 和 data.length 中也保存著同樣的值。在默認(rèn)情況下,每個(gè)可以包含內(nèi)容的元素
最多只能有一個(gè)文本節(jié)點(diǎn)
,而且必須確實(shí)有內(nèi)容存在帜消。
訪問文本子節(jié)點(diǎn):
var textNode = div.firstChild; //或者div.childNodes[0]
//取得了文本節(jié)點(diǎn)的引用后修改它棠枉。
div.firstChild.nodeValue = "Some other message";
- 在修改文本節(jié)點(diǎn)時(shí)還要注意,此時(shí)的字
符串會(huì)經(jīng)過 HTML
(或 XML,取決于文檔類型)編碼。換句話說, 小于號(hào)泡挺、大于號(hào)或引號(hào)都會(huì)像下面的例子一樣被轉(zhuǎn)義辈讶。
//輸出結(jié)果是"Some <strong>other</strong> message"
div.firstChild.nodeValue = "Some <strong>other</strong> message";
* 創(chuàng)建文本節(jié)點(diǎn)
document.createTextNode()
創(chuàng)建新文本節(jié)點(diǎn)。
- 這個(gè)方法接受一個(gè)參數(shù)——要插入節(jié)點(diǎn) 中的文本娄猫。
- 與設(shè)置已有文本節(jié)點(diǎn)的值一樣,作為參數(shù)的文本也將按照 HTML 或 XML 的格式進(jìn)行編碼贱除。
- 一般情況下,每個(gè)元素只有一個(gè)文本子節(jié)點(diǎn)。不過,在某些情況下也可能包含
多個(gè)文本子節(jié)點(diǎn)
媳溺。如果兩個(gè)文本節(jié)點(diǎn)是相鄰的同胞節(jié)點(diǎn)
,那么這兩個(gè)節(jié)點(diǎn)中的文本就會(huì)連起來顯示,中間不會(huì)有空格月幌。
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
*規(guī)范化文本節(jié)點(diǎn)
normalize()
方法:
如果 在一個(gè)包含兩個(gè)或多個(gè)文本節(jié)點(diǎn)的父元素上調(diào)用 normalize()方法,則會(huì)將所有文本節(jié)點(diǎn)合并成一個(gè) 節(jié)點(diǎn),結(jié)果節(jié)點(diǎn)的 nodeValue 等于將合并前每個(gè)文本節(jié)點(diǎn)的 nodeValue 值拼接起來的值。
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
var anotherTextNode = document.createTextNode("Yippee!");
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length); //2
element.normalize();
alert(element.childNodes.length); //1
alert(element.firstChild.nodeValue);// "Hello world!Yippee!"
* 分割文本節(jié)點(diǎn)
splitText()
方法:
這個(gè)方法會(huì)將一個(gè)文本節(jié)點(diǎn)分成兩個(gè)文本節(jié)點(diǎn),即按照指定的位置分割 nodeValue 值悬蔽。原來的文本節(jié)點(diǎn)將包含從開始到指定位 置之前的內(nèi)容,新文本節(jié)點(diǎn)將包含剩下的文本扯躺。這個(gè)方法會(huì)返回一個(gè)新文本節(jié)點(diǎn),該節(jié)點(diǎn)與原節(jié)點(diǎn)的 parentNode 相同。
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
var newNode = element.firstChild.splitText(5);
alert(element.firstChild.nodeValue); //"Hello"
alert(newNode.nodeValue); //" world!"
alert(element.childNodes.length); //2
(5) Comment類型
注釋在 DOM 中是通過 Comment 類型來表示的蝎困。
Comment 節(jié)點(diǎn)具有下列特征:
(1) nodeType 的值為 8;
(2) nodeName 的值為"#comment";
(3) nodeValue 的值是注釋的內(nèi)容;
(4) parentNode 可能是 Document 或 Element;
(5) 不支持(沒有)子節(jié)點(diǎn)录语。
Comment 類型與 Text 類型繼承自相同的基類,因此它擁有除 splitText()之外的所有字符串操作方法。
與 Text 類型相似,也可以通過
nodeValue
或data 屬性
來取得注釋的內(nèi)容禾乘。
3.document.createComment()
并為其傳遞注釋文本也可以創(chuàng)建注釋節(jié)點(diǎn)钦无。
(6) CDATASection類型
- CDATASection 類型只針對
基于 XML 的文檔
,表示的是 CDATA 區(qū)域。 - 與 Comment 類似, CDATASection 類型繼承自 Text 類型,因此擁有除 splitText()之外的所有字符串操作方法盖袭。
CDATASection 節(jié)點(diǎn)具有下列特征:
(1) nodeType 的值為 4;
(2) nodeName 的值為"#cdata-section";
(3) nodeValue 的值是 CDATA 區(qū)域中的內(nèi)容;
(4) parentNode 可能是 Document 或 Element; ? 不支持(沒有)子節(jié)點(diǎn)失暂。
CDATA 區(qū)域只會(huì)出現(xiàn)在 XML 文檔中,因此多數(shù)瀏覽器都會(huì)把 CDATA 區(qū)域
錯(cuò)誤地解析為 Comment 或 Element
。在真正的 XML 文檔中,可以使用
document.createCDataSection()
來創(chuàng)建 CDATA 區(qū)域,只需 為其傳入節(jié)點(diǎn)的內(nèi)容即可鳄虱。
(7) DocumentType類型
DocumentType 包含著與文檔的 doctype 有關(guān)的所有信息弟塞。
DocumentType具有下列特征:
(1) nodeType 的值為 10;
(2) nodeName 的值為 doctype 的名稱;
(3) nodeValue 的值為 null;
(4) parentNode 是 Document;
(5) 不支持(沒有)子節(jié)點(diǎn)。
- 在 DOM1 級(jí)中,DocumentType 對象
不能動(dòng)態(tài)創(chuàng)建
,而只能通過解析文檔代碼的方式來創(chuàng)建拙已。 - 支持它的瀏覽器會(huì)把 DocumentType 對象保存在
document.doctype
中决记。 - DOM1 級(jí)描述了 DocumentType 對象的
3 個(gè)屬性
:name、entities 和 notations倍踪。
(1)
name
表示文檔類型的名稱系宫。
(2) entities 是由文檔類型描述的實(shí)體的 NamedNodeMap 對象
(3) notations 是由文檔類型描述的符號(hào)的 NamedNodeMap 對象。
* DocumentFragment類型
- 在所有節(jié)點(diǎn)類型中,只有 DocumentFragment 在文檔中
沒有對應(yīng)的標(biāo)記
建车。 - DOM 規(guī)定文檔片段 (document fragment)是一種“輕量級(jí)”的文檔,可以包含和控制節(jié)點(diǎn),但不會(huì)像完整的文檔那樣占用
額外的資源扩借。
DocumentFragment 節(jié)點(diǎn)具有下列特征:
(1) nodeType 的值為 11;
(2) nodeName 的值為"#document-fragment";
(3) nodeValue 的值為 null;
(4) parentNode 的值為 null;
(5) 子節(jié)點(diǎn)可以是 Element、ProcessingInstruction 缤至、Comment潮罪、Text、CDATASection 或EntityReference。
- 雖然不能把文檔片段直接添加到文檔中,但可以將它作為一個(gè)“倉庫”來使用,即可以在里面保存將來可能會(huì)添加到文檔中的節(jié)點(diǎn)嫉到。
document.createDocumentFragment()方法
:創(chuàng)建文檔片段沃暗。
var fragment = document.createDocumentFragment();
- 如果將文檔中的節(jié)點(diǎn)添加到文檔片段中,就會(huì)從文檔樹中移除該節(jié)點(diǎn),也不會(huì)從瀏覽器中再看到該節(jié)點(diǎn)。添加到文檔片段 中的新節(jié)點(diǎn)同樣也不屬于文檔樹何恶。
- 可以通過 appendChild()或 insertBefore()將文檔片段中內(nèi)容添 加到文檔中孽锥。在將文檔片段作為參數(shù)傳遞給這兩個(gè)方法時(shí),實(shí)際上
只會(huì)將文檔片段的所有子節(jié)點(diǎn)添加到相應(yīng)位置上
;文檔片段本身永遠(yuǎn)不會(huì)成為文檔樹的一部分。
(5) Attr類型
元素的特性在 DOM 中以 Attr 類型來表示细层。
- 從技術(shù)角度講,特性就是存在于元素的 attributes 屬性中的節(jié)點(diǎn)忱叭。
特性節(jié)點(diǎn)具有 下列特征:
(1) nodeType 的值為 2;
(2) nodeName 的值是特性的名稱;
(3) nodeValue 的值是特性的值;
(4) parentNode 的值為 null;
(5) 在 HTML 中不支持(沒有)子節(jié)點(diǎn);
(6) 在 XML 中子節(jié)點(diǎn)可以是 Text 或 EntityReference。
盡管它們也是節(jié)點(diǎn),但特性卻不被認(rèn)為是 DOM 文檔樹的一部分今艺。
Attr 對象有
3 個(gè)屬性
:name韵丑、value 和 specified。
(1) name 是特性名稱(與 nodeName 的 值相同)虚缎。
(2) value 是特性的值(與 nodeValue 的值相同)撵彻。
(3) specified 是一個(gè)布爾值,用以區(qū)別特性是在代碼中指定的,還是默認(rèn)的。
document.createAttribute()
并傳入特性的名稱可以創(chuàng)建新的特性節(jié)點(diǎn)实牡。
setAttributeNode()
方法:將新創(chuàng)建的特性添加到元素中陌僵。
訪問特性:
attributes 屬性、getAttributeNode()方法以及 getAttribute()方法创坞。其中,attributes和 getAttributeNode()都會(huì)返回對應(yīng)特性的 Attr 節(jié)點(diǎn),而 getAttribute()則只返回特性的值碗短。
var attr = document.createAttribute("align");
attr.value = "left";
element.setAttributeNode(attr);
alert(element.attributes["align"].value);//"left"
alert(element.getAttributeNode("align").value); //"left"
alert(element.getAttribute("align")); //"left"
2. DOM 操作技術(shù)
(1) 動(dòng)態(tài)腳本
創(chuàng)建動(dòng)態(tài)腳本有兩種方式:插入外部文件
和直接插入 JavaScript 代碼
。
* 加載外部的 JavaScript 文件
function loadScript(url){
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
loadScript("client.js");
* 指定 JavaScript 代碼
function loadScriptString(code){
var script = document.createElement("script");
script.type = "text/javascript";
try {
script.appendChild(document.createTextNode(code));
} catch (ex){
script.text = code;
}
document.body.appendChild(script);
}
loadScriptString("function sayHi(){alert('hi');}");
IE 將<script>視為一個(gè)特殊的元素,不允許 DOM 訪問其子節(jié)點(diǎn)题涨。不過,可以使用<script>元素的
text 屬性
來指定 JavaScript 代碼偎谁。
(2) 動(dòng)態(tài)樣式
與動(dòng)態(tài)腳本類似,所謂動(dòng)態(tài)樣式是指在頁面剛加載時(shí)不存在的樣式;動(dòng)態(tài)樣式是在頁面加載完成后動(dòng)態(tài)添加到頁面中的。
- 能夠把 CSS 樣式包含到 HTML 頁面中的元素有兩個(gè)纲堵。其中,
<link>元素
用于包含來自外部的文件, 而<style>元素
用于指定嵌入的樣式巡雨。
*<link>元素
<link rel="stylesheet" type="text/css" href="styles.css">
function loadStyles(url){
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = url;
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
}
loadStyles("styles.css");
* <style>元素
<style type="text/css">
body {
background-color: red;
}
</style>
function loadStyleString(css){
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode(css));
} catch (ex){
style.styleSheet.cssText = css;
}
var head = document.getElementsByTagName("head")[0];
head.appendChild(style);
}
loadStyleString("body{background-color:red}");
IE 將<style>視為 一個(gè)特殊的、與<script>類似的節(jié)點(diǎn),不允許訪問其子節(jié)點(diǎn)席函。解決 IE 中這個(gè)問題的辦法,就是訪問元素的 styleSheet 屬性, 該屬性又有一個(gè) cssText 屬性,可以接受 CSS 代碼铐望。
(3) 操作表格
*<table>元素添加的屬性和方法
(1) caption:保存著對<caption>元素(如果有)的指針。
(2) tBodies:是一個(gè)<tbody>元素的 HTMLCollection茂附。
(3) tFoot:保存著對<tfoot>元素(如果有)的指針正蛙。
(4) tHead:保存著對<thead>元素(如果有)的指針。
(5) rows:是一個(gè)表格中所有行的 HTMLCollection营曼。
(6) createTHead():創(chuàng)建<thead>元素,將其放到表格中,返回引用乒验。
(7) createTFoot():創(chuàng)建<tfoot>元素,將其放到表格中,返回引用。
(8) createCaption():創(chuàng)建<caption>元素,將其放到表格中,返回引用溶推。 ? deleteTHead():刪除<thead>元素徊件。
(9) deleteTFoot():刪除<tfoot>元素。
(10) deleteCaption():刪除<caption>元素蒜危。
(11) deleteRow(pos):刪除指定位置的行虱痕。
(12) insertRow(pos):向 rows 集合中的指定位置插入一行。
*為<tbody>元素添加的屬性和方法
(1) rows:保存著<tbody>元素中行的 HTMLCollection辐赞。
(2) deleteRow(pos):刪除指定位置的行部翘。
(3) insertRow(pos):向 rows 集合中的指定位置插入一行,返回對新插入行的引用。
*<tr>元素添加的屬性和方法
(1) cells:保存著<tr>元素中單元格的 HTMLCollection响委。
(2) deleteCell(pos):刪除指定位置的單元格新思。
(3) insertCell(pos):向 cells 集合中的指定位置插入一個(gè)單元格,返回對新插入單元格的引用。
<table border="1" width="100%">
<tbody>
<tr>
<td>Cell 1,1</td>
<td>Cell 2,1</td>
</tr>
<tr>
<td>Cell 1,2</td>
<td>Cell 2,2</td>
</tr>
</tbody>
</table>
//創(chuàng)建 table
var table = document.createElement("table");
table.border = 1;
table.width = "100%";
//創(chuàng)建 tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
//創(chuàng)建第一行
tbody.insertRow(0);
tbody.rows[0].insertCell(0);
tbody.rows[0].cells[0].appendChild(document.createTextNode("Cell 1,1"));
tbody.rows[0].insertCell(1);
tbody.rows[0].cells[1].appendChild(document.createTextNode("Cell 2,1"));
//創(chuàng)建第二行
tbody.insertRow(1);
tbody.rows[1].insertCell(0);
tbody.rows[1].cells[0].appendChild(document.createTextNode("Cell 1,2"));
tbody.rows[1].insertCell(1);
tbody.rows[1].cells[1].appendChild(document.createTextNode("Cell 2,2"));
//將表格添加到文檔主體中
document.body.appendChild(table);
(4) 使用NodeList
NodeList 及其“近親”NamedNodeMap 和 HTMLCollection,這三個(gè)集合都是“動(dòng)態(tài)的”;換句話說,每當(dāng)文檔結(jié)構(gòu)發(fā)生變化時(shí),它們都會(huì)得到更新赘风。因 此,它們始終都會(huì)保存著最新夹囚、最準(zhǔn)確的信息。
如果想要迭代一個(gè) NodeList,最好是使用 length 屬性初始化第二個(gè)變量,然后將迭代器與該變量進(jìn)行比較邀窃。
var divs = document.getElementsByTagName("div"),i,len, div;
for (i=0, len=divs.length; i < len; i++){
div = document.createElement("div");
document.body.appendChild(div);
}