JavaScript 高級(jí)程序設(shè)計(jì)(第10章 DOM)

第10章 DOM

1. 節(jié)點(diǎn)層次

文檔節(jié)點(diǎn)是每個(gè)文檔的根節(jié)點(diǎn)昆庇。

(1) Node 類型
  1. 每個(gè)節(jié)點(diǎn)都有一個(gè) nodeType 屬性,用于表明節(jié)點(diǎn)的類型。
  2. 節(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)吼旧。

  1. IE 沒有公開 Node 類型的構(gòu)造函數(shù),為了確被宋跨瀏覽器兼容,最好還是將nodeType 屬性與數(shù)字值進(jìn)行比較。
nodeNamenodeValue 屬性
* 節(jié)點(diǎn)關(guān)系
    1. 每個(gè)節(jié)點(diǎn)都有一個(gè) childNodes 屬性,其中保存著一個(gè) NodeList 對象圈暗。
  • 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;
    }
    1. 每個(gè)節(jié)點(diǎn)都有一個(gè) parentNode屬性,該屬性指向文檔樹中的父節(jié)點(diǎn)。

包含在 childNodes 列表中 的所有節(jié)點(diǎn)都具有相同的父節(jié)點(diǎn),因此它們的 parentNode 屬性都指向同一個(gè)節(jié)點(diǎn)寸齐。

    1. 包含在 childNodes 列表中的每個(gè)節(jié)點(diǎn)相互之間都是同胞節(jié)點(diǎn)欲诺。通過使用列表中每個(gè)節(jié)點(diǎn)的 previousSiblingnextSibling 屬性,可以訪問同一列表中的其他節(jié)點(diǎn)。
    1. 父節(jié)點(diǎn)的 firstChildlastChild 屬性分別指向其 childNodes 列表中的第一個(gè)和最后一個(gè)節(jié)點(diǎn)渺鹦。
      節(jié)點(diǎn)關(guān)系
  • 5.hasChildNodes()方法在節(jié)點(diǎn)包含一或多個(gè)子節(jié)點(diǎn)的情況下返回 true扰法。

    1. ownerDocument屬性指向表示整個(gè)文檔的文檔節(jié)點(diǎn)。
* 操作節(jié)點(diǎn)
  1. 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
  1. 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)將成為方法的返回值。

* 其他方法
  1. 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類型
  1. JavaScript 通過 Document 類型表示文檔放接。
  2. 在瀏覽器中,document 對象是 HTMLDocument(繼承自 Document 類型)的一個(gè)實(shí)例,表示整個(gè) HTML 頁面刺啦。
  3. 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)的快捷方式

  1. documentElement 屬性,該屬性始終指向 HTML 頁面中的<html>元素。
  2. 通過 childNodes 列表訪問文檔元素渺绒。
  1. document.body,body 屬性,直接指向<body>元素贺喝。

3.Document 另一個(gè)可能的子節(jié)點(diǎn)是 DocumentType。通常將<!DOCTYPE>標(biāo)簽看成一個(gè)與文檔其他 部分不同的實(shí)體,可以通過 doctype 屬性(在瀏覽器中是 document.doctype)來訪問它的信息宗兼。

* 文檔信息
  1. title屬性:可以取得當(dāng)前頁面的標(biāo)題,也可以修改當(dāng)前頁面的標(biāo)題并反映在瀏覽器的標(biāo)題欄中躏鱼。(document.title)

  2. URL屬性:包含頁面完整的 URL(即地址欄中顯示的 URL)。(document.URL)

  3. domain 屬性:只包含頁面的域名殷绍。(document.domain)

  4. 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ò)!)
*查找元素
  1. getElementById()

(1) 接收一個(gè)參數(shù):要取得的元素的 ID牧牢。如果找到相應(yīng)的元素則返回該元素,如果不存在帶有相應(yīng) ID 的元素,則返回 null看锉。
(2) 如果頁面中多個(gè)元素的 ID 值相同,getElementById()只返回文檔中第一次出現(xiàn)的元素
(3) ID 必須與頁面中元素的 id 特性(attribute)嚴(yán)格匹配,包括大小寫

  1. 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");
DOM 功能
* 文檔寫入

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。

  1. 要訪問元素的標(biāo)簽名,可以使用 nodeName 屬性,也可以使用 tagName 屬性;
  2. 在 HTML 中,標(biāo)簽名始終都以全部大寫表示,div.tagName 實(shí)際上輸出的是 "DIV"而非"div"匹表。
*HTML元素
  1. 所有 HTML 元素都由 HTMLElement 類型表示,不是直接通過這個(gè)類型,也是通過它的子類型來表示门坷。
  2. 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()方法:

  1. 通過 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()方法:

  1. 這個(gè)方法 接受兩個(gè)參數(shù):要設(shè)置的特性名和值瞳秽。如果特性已經(jīng)存在,setAttribute()會(huì)以指定的值替換現(xiàn)有的值;如果特性不存在,setAttribute() 則創(chuàng)建該屬性并設(shè)置相應(yīng)的值瓣履。
  2. 通過這個(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)脯宿。

  1. 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";
  1. 調(diào)用 removeNamedItem()方法與在元素上調(diào)用 removeAttribute()方法的效果相同——直接刪 除具有給定名稱的特性。兩個(gè)方法間唯一的區(qū)別,即 removeNamedItem()返回表示 被刪除特性的 Attr 節(jié)點(diǎn)连霉。

  2. 針對 attributes 對象中的特性,不同瀏覽器返回的順序不同榴芳。這些特性在 XML 或 HTML 代 碼中出現(xiàn)的先后順序,不一定與它們出現(xiàn)在 attributes 對象中的順序一致。

  3. 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)建新元素柿祈。

  1. 這個(gè)方法只接受一個(gè)參數(shù),即要?jiǎng)?chuàng)建元素的標(biāo)簽名。

  2. 這個(gè)標(biāo)簽名在 HTML 文檔中不區(qū)分大小寫,而在 XML(包括 XHTML)文檔中,則是區(qū) 分大小寫的哩至。

  3. IE 中可以以另一種方式使用 createElement(),即為這個(gè)方法傳入完整的元素標(biāo)簽,也可以包含屬性躏嚎。


var div = document.createElement("<div id=\"myNewDiv\" 
class=\"box\"></div >");
*元素的子節(jié)點(diǎn)
  1. 元素的 childNodes 屬性中包含了它的所有子節(jié)點(diǎn),這些子節(jié)點(diǎn)有可能是元素、文本節(jié)點(diǎn)菩貌、注釋或處理指令卢佣。

  2. 不同瀏覽器在看待這些節(jié)點(diǎn)方面存在顯著的不同,返回的子節(jié)點(diǎn)不相同箭阶。

  3. 如果需要通過 childNodes 屬性遍歷子節(jié)點(diǎn)虚茶,要先檢查 一下 nodeTpye 屬性。

for (var i=0, len=element.childNodes.length; i < len; i++){
if (element.childNodes[i].nodeType == 1){ 12
//執(zhí)行某些操作 }
}
  1. 元素也支持 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 類型
  1. 文本節(jié)點(diǎn)由 Text 類型表示,包含的是可以照字面解釋的純文本內(nèi)容。
  2. 純文本中可以包含轉(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)罩扇。

  1. 通過 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 為止
處的字符串滩届。

  1. 文本節(jié)點(diǎn)還有一個(gè) length 屬性,保存著節(jié)點(diǎn)中字符的數(shù)目。而且,nodeValue.length 和 data.length 中也保存著同樣的值。

  2. 在默認(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";
  1. 在修改文本節(jié)點(diǎn)時(shí)還要注意,此時(shí)的字符串會(huì)經(jīng)過 HTML(或 XML,取決于文檔類型)編碼。換句話說, 小于號(hào)泡挺、大于號(hào)或引號(hào)都會(huì)像下面的例子一樣被轉(zhuǎn)義辈讶。
//輸出結(jié)果是"Some &lt;strong&gt;other&lt;/strong&gt; message" 
div.firstChild.nodeValue = "Some <strong>other</strong> message";
* 創(chuàng)建文本節(jié)點(diǎn)

document.createTextNode()創(chuàng)建新文本節(jié)點(diǎn)。

  1. 這個(gè)方法接受一個(gè)參數(shù)——要插入節(jié)點(diǎn) 中的文本娄猫。
  2. 與設(shè)置已有文本節(jié)點(diǎn)的值一樣,作為參數(shù)的文本也將按照 HTML 或 XML 的格式進(jìn)行編碼贱除。
  3. 一般情況下,每個(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)录语。

  1. Comment 類型與 Text 類型繼承自相同的基類,因此它擁有除 splitText()之外的所有字符串操作方法。

  2. 與 Text 類型相似,也可以通過nodeValuedata 屬性來取得注釋的內(nèi)容禾乘。

3.document.createComment()并為其傳遞注釋文本也可以創(chuàng)建注釋節(jié)點(diǎn)钦无。

(6) CDATASection類型
  1. CDATASection 類型只針對基于 XML 的文檔,表示的是 CDATA 區(qū)域。
  2. 與 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)失暂。

  1. CDATA 區(qū)域只會(huì)出現(xiàn)在 XML 文檔中,因此多數(shù)瀏覽器都會(huì)把 CDATA 區(qū)域錯(cuò)誤地解析為 Comment 或 Element

  2. 在真正的 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)。

  1. 在 DOM1 級(jí)中,DocumentType 對象不能動(dòng)態(tài)創(chuàng)建,而只能通過解析文檔代碼的方式來創(chuàng)建拙已。
  2. 支持它的瀏覽器會(huì)把 DocumentType 對象保存在 document.doctype 中决记。
  3. DOM1 級(jí)描述了 DocumentType 對象的 3 個(gè)屬性:name、entities 和 notations倍踪。

(1) name表示文檔類型的名稱系宫。
(2) entities 是由文檔類型描述的實(shí)體的 NamedNodeMap 對象
(3) notations 是由文檔類型描述的符號(hào)的 NamedNodeMap 對象。

* DocumentFragment類型
  1. 在所有節(jié)點(diǎn)類型中,只有 DocumentFragment 在文檔中沒有對應(yīng)的標(biāo)記建车。
  2. 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。

  1. 雖然不能把文檔片段直接添加到文檔中,但可以將它作為一個(gè)“倉庫”來使用,即可以在里面保存將來可能會(huì)添加到文檔中的節(jié)點(diǎn)嫉到。

document.createDocumentFragment()方法:創(chuàng)建文檔片段沃暗。

var fragment = document.createDocumentFragment();
  1. 如果將文檔中的節(jié)點(diǎn)添加到文檔片段中,就會(huì)從文檔樹中移除該節(jié)點(diǎn),也不會(huì)從瀏覽器中再看到該節(jié)點(diǎn)。添加到文檔片段 中的新節(jié)點(diǎn)同樣也不屬于文檔樹何恶。
  2. 可以通過 appendChild()或 insertBefore()將文檔片段中內(nèi)容添 加到文檔中孽锥。在將文檔片段作為參數(shù)傳遞給這兩個(gè)方法時(shí),實(shí)際上只會(huì)將文檔片段的所有子節(jié)點(diǎn)添加到相應(yīng)位置上;文檔片段本身永遠(yuǎn)不會(huì)成為文檔樹的一部分。
(5) Attr類型

元素的特性在 DOM 中以 Attr 類型來表示细层。

  1. 從技術(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。

  1. 盡管它們也是節(jié)點(diǎn),但特性卻不被認(rèn)為是 DOM 文檔樹的一部分今艺。

  2. 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)添加到頁面中的。

  1. 能夠把 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);
 }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荸哟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瞬捕,更是在濱河造成了極大的恐慌鞍历,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肪虎,死亡現(xiàn)場離奇詭異劣砍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扇救,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門刑枝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迅腔,你說我怎么就攤上這事仅讽。” “怎么了钾挟?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵洁灵,是天一觀的道長。 經(jīng)常有香客問我掺出,道長徽千,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任汤锨,我火速辦了婚禮双抽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闲礼。我一直安慰自己牍汹,他們只是感情好铐维,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著慎菲,像睡著了一般嫁蛇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上露该,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天睬棚,我揣著相機(jī)與錄音,去河邊找鬼解幼。 笑死抑党,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的撵摆。 我是一名探鬼主播底靠,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼特铝!你這毒婦竟也來了苛骨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤苟呐,失蹤者是張志新(化名)和其女友劉穎痒芝,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牵素,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡严衬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了笆呆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片请琳。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赠幕,靈堂內(nèi)的尸體忽然破棺而出俄精,到底是詐尸還是另有隱情,我是刑警寧澤榕堰,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布竖慧,位于F島的核電站,受9級(jí)特大地震影響逆屡,放射性物質(zhì)發(fā)生泄漏圾旨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一魏蔗、第九天 我趴在偏房一處隱蔽的房頂上張望砍的。 院中可真熱鬧,春花似錦莺治、人聲如沸廓鞠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽床佳。三九已至滋早,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夕土,已是汗流浹背馆衔。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工瘟判, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怨绣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓拷获,卻偏偏與公主長得像篮撑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子匆瓜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容