DOM 可以將任何 HTML 或 XML 文檔描繪成一個(gè)由多層節(jié)點(diǎn)構(gòu)成的結(jié)構(gòu)丰包。
一饶唤、節(jié)點(diǎn)層次結(jié)構(gòu)
node類型
每個(gè)節(jié)點(diǎn)都有一個(gè) nodeType 屬性肄程,用于表明節(jié)點(diǎn)的類型睦擂;所有節(jié)點(diǎn)都有的最后一個(gè)屬性是 ownerDocument得湘,該屬性指向表示整個(gè)文檔的文檔節(jié)點(diǎn)
操作節(jié)點(diǎn)
appendChild()
insertBefore()
replaceChild()
removeChild()
cloneNode()
Document類型
document的特點(diǎn):
1、nodeType 的值為 9顿仇;
2淘正、nodeName 的值為"#document";
3臼闻、nodeValue 的值為 null鸿吆;
4、parentNode 的值為 null述呐;
5惩淳、ownerDocument 的值為 null
文檔信息:
document.domain
document.referrer
document.URL
document.title
文檔寫入:
write()、 writeln()乓搬、 open()和 close()
查找元素:
document.getElementById()--通過id獲取單個(gè)元素;
document.getElementsByClassName()--通過類名獲取元素
document.getElementsByTagName()--通過標(biāo)簽名獲取元素
document.querySelector()--通過樣式選擇器獲取單個(gè)元素
document.querySelectorAll()--通過樣式選擇器獲取所有元素;
特殊的快捷方式:
document.anchors:帶 name 特性的<a>元素
document.applets
document.links:帶 href 特性的<a>元素
document.forms= document.getElementsByTagName("form")
document.images=document.getElementsByTagName
("img")
element類型
element類型特點(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稿辙。
Element 類型是使用 attributes 屬性的唯一一個(gè) DOM 節(jié)點(diǎn)類型
獲取屬性:(值與節(jié)點(diǎn))
getAttribute()邻储、getAttributeNode()
setAttribute()吨娜、setAttributeNode()
removeAttribute()宦赠、removeAttributeNode()
創(chuàng)造元素:
document.createElement()
元素的子節(jié)點(diǎn):
childNodes
childrden
attributes屬性:
<h1 style="color:red" name="h1" id="h1" class="h1">Hello World</h1>
var b=document.getElementById("h1");
console.log(b.attributes);
getNamedItem(name):返回 nodeName 屬性等于 name 的節(jié)點(diǎn)毡琉;
removeNamedItem(name):從列表中移除 nodeName 屬性等于 name 的節(jié)點(diǎn)桅滋;
setNamedItem(node):向列表中添加節(jié)點(diǎn)丐谋,以節(jié)點(diǎn)的 nodeName 屬性為索引号俐;
item(pos):返回位于數(shù)字 pos 位置處的節(jié)點(diǎn)
text屬性
可以通過 nodeValue 屬性或 data 屬性訪問 Text 節(jié)點(diǎn)中包含的文本
text屬性特點(diǎn):
1萧落、nodeType 的值為 3找岖;
2许布、nodeName 的值為"#text"蜜唾;
3袁余、nodeValue 的值為節(jié)點(diǎn)所包含的文本颖榜;
4掩完、 parentNode 是一個(gè) Element且蓬;
5恶阴、不支持(沒有)子節(jié)點(diǎn)耘斩。
使用下列方法可以操作節(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 為止處的字符串暇检。
創(chuàng)建文本節(jié)點(diǎn):
document.createTextNode
合并和分割文本節(jié)點(diǎn)
1、合并文本節(jié)點(diǎn):如果在一個(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!"
2、分割文本節(jié)點(diǎn):splitText()這個(gè)方法會(huì)將一個(gè)文本節(jié)點(diǎn)分成兩個(gè)文本節(jié)點(diǎn)悔据,即按照指定的位置分割 nodeValue 值
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
comment類型
comment類型的特點(diǎn):
1庄敛、nodeType 的值為 8;
2科汗、nodeName 的值為"#comment"藻烤;
3怖亭、nodeValue 的值是注釋的內(nèi)容倾芝;
4拯刁、parentNode 可能是 Document 或 Element帚桩;
5郭蕉、不支持(沒有)子節(jié)點(diǎn)
Comment 類型與 Text 類型繼承自相同的基類涨岁,因此它擁有除 splitText()之外的所有字符串操作方法甜攀。
CDATASection 類型
CDATASection 類型只針對(duì)基于 XML 的文檔姥敛,表示的是 CDATA 區(qū)域。與 Comment 類似,CDATASection 類型繼承自 Text 類型之剧,因此擁有除 splitText()之外的所有字符串操作方法。
基本特征:
nodeType 的值為 4;
nodeName 的值為"#cdata-section"胸完;
nodeValue 的值是 CDATA 區(qū)域中的內(nèi)容;
parentNode 可能是 Document 或 Element斋竞;
不支持(沒有)子節(jié)點(diǎn)绢要。
DocumentType類型
DocumentType 類型在 Web 瀏覽器中并不常用铅搓,僅有 Firefox外盯、 Safari 和 Opera 支持它剧罩,支持 它 的 瀏覽 器 會(huì) 把 DocumentType 對(duì) 象 保 存 在 document.doctype 中 界牡。
DOM1 級(jí) 描 述 了
DocumentType 對(duì)象的 3 個(gè)屬性: name平绩、 entities 和 notations骇扇。其中少孝, name 表示文檔類型的名稱;entities 是由文檔類型描述的實(shí)體的 NamedNodeMap 對(duì)象熬苍; notations 是由文檔類型描述的符號(hào)的NamedNodeMap 對(duì)象稍走。
DocumentFragment類型
DocumentFragment類型是一個(gè)比較有用的東西,雖然不能把文檔片段直接添加到文檔中柴底,但可以將它作為一個(gè)“倉(cāng)庫(kù)”來使用婿脸,即可以在里面保存將來可能會(huì)添加到文檔中的節(jié)點(diǎn)。
例如:如果逐個(gè)地添加列表項(xiàng)柄驻,將會(huì)導(dǎo)致瀏覽器反復(fù)渲染(呈現(xiàn))新信息狐树。為避免這個(gè)問題,可以像下面這樣使用一個(gè)文檔片段來保存創(chuàng)建的列表項(xiàng)鸿脓,然后再一次性將它們添加到文檔中抑钟。
var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i=0; i < 3; i++){
li = document.createElement("li");
li.appendChild(document.createTextNode("Item " + (i+1)));
fragment.appendChild(li);
}
ul.appendChild(fragment);
Attr類型
基本特征:
1、nodeType 的值為 2野哭;
2在塔、nodeName 的值是特性的名稱;
3拨黔、nodeValue 的值是特性的值蛔溃;
4、parentNode 的值為 null;
5贺待、在 HTML 中不支持(沒有)子節(jié)點(diǎn)徽曲;
6、在 XML 中子節(jié)點(diǎn)可以是 Text 或 EntityReference麸塞。
document.createAttribute()
開發(fā)人員最常使用的是 getAttribute()疟位、 setAttribute()和 remveAttribute()方法,很少直接引用特性節(jié)點(diǎn)喘垂。
二、DOM操作
動(dòng)態(tài)腳本
考慮到IE瀏覽器的兼容性
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);
}
動(dòng)態(tài)樣式
考慮IE瀏覽器兼容性
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);
}
操作表格
操作表格是一個(gè)復(fù)雜的事情绍撞,例如要使用 DOM 來創(chuàng)建下面的 HTML 表格
<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>
代碼過于冗長(zhǎng)....
//創(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)建第一行
var row1 = document.createElement("tr");
tbody.appendChild(row1);
var cell1_1 = document.createElement("td");
cell1_1.appendChild(document.createTextNode("Cell 1,1"));
row1.appendChild(cell1_1);
var cell2_1 = document.createElement("td");
cell2_1.appendChild(document.createTextNode("Cell 2,1"));
row1.appendChild(cell2_1);
//創(chuàng)建第二行
var row2 = document.createElement("tr");
tbody.appendChild(row2);
var cell1_2 = document.createElement("td");
cell1_2.appendChild(document.createTextNode("Cell 1,2"));
row2.appendChild(cell1_2);
var cell2_2= document.createElement("td");
cell2_2.appendChild(document.createTextNode("Cell 2,2"));
row2.appendChild(cell2_2);
//將表格添加到文檔主體中
document.body.appendChild(table);
HTML DOM 為<table>正勒、 <tbody>和<tr>元素添加了一些屬性和方法,使得操作表格相對(duì)方便,可以極大地減少代碼量傻铣。
為<table>元素添加的屬性和方法如下:
caption:保存著對(duì)<caption>元素(如果有)的指針章贞。
tBodies:是一個(gè)<tbody>元素的 HTMLCollection。
tFoot:保存著對(duì)<tfoot>元素(如果有)的指針非洲。
tHead:保存著對(duì)<thead>元素(如果有)的指針鸭限。
rows:是一個(gè)表格中所有行的 HTMLCollection。
createTHead():創(chuàng)建<thead>元素两踏,將其放到表格中败京,返回引用。
createTFoot():創(chuàng)建<tfoot>元素梦染,將其放到表格中赡麦,返回引用。
createCaption():創(chuàng)建<caption>元素帕识,將其放到表格中泛粹,返回引用。
deleteTHead():刪除<thead>元素肮疗。
deleteTFoot():刪除<tfoot>元素晶姊。
deleteCaption():刪除<caption>元素。
deleteRow(pos):刪除指定位置的行伪货。
insertRow(pos):向 rows 集合中的指定位置插入一行们衙。
為<tbody>元素添加的屬性和方法如下:
rows:保存著<tbody>元素中行的 HTMLCollection。
deleteRow(pos):刪除指定位置的行超歌。
insertRow(pos):向 rows 集合中的指定位置插入一行砍艾,返回對(duì)新插入行的引用。
為<tr>元素添加的屬性和方法如下:
cells:保存著<tr>元素中單元格的 HTMLCollection巍举。
deleteCell(pos):刪除指定位置的單元格脆荷。
insertCell(pos):向 cells 集合中的指定位置插入一個(gè)單元格,返回對(duì)新插入單元格的引用
三、DOM擴(kuò)展
元素遍歷(Element Traversal )
Element Traversal API 為 DOM 元素添加了以下 5 個(gè)屬性:
childElementCount:返回子元素(不包括文本節(jié)點(diǎn)和注釋)的個(gè)數(shù)蜓谋。
firstElementChild:指向第一個(gè)子元素梦皮; firstChild 的元素版。
lastElementChild:指向最后一個(gè)子元素桃焕; lastChild 的元素版剑肯。
previousElementSibling:指向前一個(gè)同輩元素; previousSibling 的元素版观堂。
nextElementSibling:指向后一個(gè)同輩元素让网; nextSibling 的元素版
HTML5相關(guān)擴(kuò)充
1、 classList 屬性
在操作類名時(shí)师痕,需要通過 className 屬性添加溃睹、刪除和替換類名。因?yàn)?className 中是一個(gè)字符串胰坟,所以即使只修改字符串一部分因篇,也必須每次都設(shè)置整個(gè)字符串的值。ClassList可以簡(jiǎn)化對(duì)類名的操作笔横。
add(value):將給定的字符串值添加到列表中竞滓。如果值已經(jīng)存在,就不添加了吹缔。
contains(value):表示列表中是否存在給定的值商佑,如果存在則返回 true,否則返回 false厢塘。
remove(value):從列表中刪除給定的字符串莉御。
toggle(value):如果列表中已經(jīng)存在給定的值,刪除它俗冻;如果列表中沒有給定的值礁叔,添加它
item(index):返回指定的類名
2、焦點(diǎn)
document.activeElement 屬性迄薄,這個(gè)屬性始終會(huì)引用 DOM 中當(dāng)前獲得了焦點(diǎn)的元素
document.hasFocus()方法琅关,這個(gè)方法用于確定文檔是否獲得了焦點(diǎn)
3、document的變化
document.readyState 屬性:
--> loading讥蔽,正在加載文檔涣易;
--> complete,已經(jīng)加載完文檔
document.compatMode屬性:這個(gè)屬性就是為了告訴開發(fā)人員瀏
覽器采用了哪種渲染模式
document.head屬性:獲取html頭
document.charset屬性: html字符集
4冶伞、自定義數(shù)據(jù)屬性
HTML5規(guī)定可以為元素添加非標(biāo)準(zhǔn)的屬性新症,但要添加前綴 data-,目的是為元素提供與渲染無關(guān)的信息响禽,或者提供語(yǔ)義信息徒爹,使用dataset獲取荚醒。
<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>
//本例中使用的方法僅用于演示
var div = document.getElementById("myDiv");
//取得自定義屬性的值
var appId = div.dataset.appId;
var myName = div.dataset.myname;
//設(shè)置值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
5、插入標(biāo)記
- innerHTML 屬性
在讀模式下隆嗅, innerHTML 屬性返回與調(diào)用元素的所有子節(jié)點(diǎn)(包括元素界阁、注釋和文本節(jié)點(diǎn))對(duì)應(yīng)的 HTML 標(biāo)記。
為 innerHTML 設(shè)置 HTML 字符串后胖喳,瀏覽器會(huì)將這個(gè)字符串解析為相應(yīng)的 DOM樹泡躯。 - outerHTML 屬性
在讀模式下, outerHTML 返回調(diào)用它的元素及所有子節(jié)點(diǎn)的 HTML 標(biāo)簽丽焊。在寫模式下较剃, outerHTML會(huì)根據(jù)指定的 HTML 字符串創(chuàng)建新的 DOM 子樹然后用這個(gè) DOM 子樹完全替換調(diào)用元素。 - insertAdjacentHTML()方法
接收兩個(gè)參數(shù):插入位置和要插入的 HTML 文本技健。第一個(gè)參數(shù)必須是下列值之一:
"beforebegin"重付,在當(dāng)前元素之前插入一個(gè)緊鄰的同輩元素;
"afterbegin"凫乖,在當(dāng)前元素之下插入一個(gè)新的子元素或在第一個(gè)子元素之前再插入新的子元素;
"beforeend"弓颈,在當(dāng)前元素之下插入一個(gè)新的子元素或在最后一個(gè)子元素之后再插入新的子元素帽芽;
"afterend",在當(dāng)前元素之后插入一個(gè)緊鄰的同輩元素翔冀。
第二個(gè)參數(shù)是一個(gè) HTML 字符串(與 innerHTML 和 outerHTML的值相同)
//作為前一個(gè)同輩元素插入
element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");
//作為第一個(gè)子元素插入
element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>");
//作為最后一個(gè)子元素插入
element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>");
//作為后一個(gè)同輩元素插入
element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");
注意:
在插入大量新 HTML 標(biāo)記時(shí)导街,使用 innerHTML 屬性與通過多次 DOM 操作先創(chuàng)建節(jié)點(diǎn)再指定它們之間的關(guān)系相比,效率要高得多纤子。但是要注意性能問題搬瑰,不能頻繁使用。
四控硼、DOM事件
事件流
“DOM2級(jí)事件”規(guī)定的事件流包括三個(gè)階段:事件捕獲階段泽论、處于目標(biāo)階段和事件冒泡階段。
事件冒泡:從最內(nèi)層到最外層
事件捕獲:從最外層到最內(nèi)層
事件處理
“DOM2 級(jí)事件” 定義了兩個(gè)方法卡乾,用于處理指定和刪除事件處理程序的操作: addEventListener()和 removeEventListener()翼悴。用這兩個(gè)方法就行咯
事件對(duì)象
在觸發(fā) DOM 上的某個(gè)事件時(shí),會(huì)產(chǎn)生一個(gè)事件對(duì)象 event幔妨,這個(gè)對(duì)象中包含著所有與事件有關(guān)的信息鹦赎。
event 對(duì)象包含與創(chuàng)建它的特定事件有關(guān)的屬性和方法: