DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。
一、节点层次结构
node类型
每个节点都有一个 nodeType 属性,用于表明节点的类型;所有节点都有的最后一个属性是 ownerDocument,该属性指向表示整个文档的文档节点
操作节点
appendChild()
insertBefore()
replaceChild()
removeChild()
cloneNode()
Document类型
document的特点:
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获取单个元素;
document.getElementsByClassName()--通过类名获取元素
document.getElementsByTagName()--通过标签名获取元素
document.querySelector()--通过样式选择器获取单个元素
document.querySelectorAll()--通过样式选择器获取所有元素;
特殊的快捷方式:
document.anchors:带 name 特性的<a>元素
document.applets
document.links:带 href 特性的<a>元素
document.forms= document.getElementsByTagName("form")
document.images=document.getElementsByTagName
("img")
element类型
element类型特点:
1、nodeType 的值为 1;
2、nodeName 的值为元素的标签名;
3、nodeValue 的值为 null;
4、parentNode 可能是 Document 或 Element;
5、其子节点可能是 Element、 Text、 Comment、 ProcessingInstruction、 CDATASection 或EntityReference。
Element 类型是使用 attributes 属性的唯一一个 DOM 节点类型
获取属性:(值与节点)
getAttribute()、getAttributeNode()
setAttribute()、setAttributeNode()
removeAttribute()、removeAttributeNode()
创造元素:
document.createElement()
元素的子节点:
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);
图片.png
getNamedItem(name):返回 nodeName 属性等于 name 的节点;
removeNamedItem(name):从列表中移除 nodeName 属性等于 name 的节点;
setNamedItem(node):向列表中添加节点,以节点的 nodeName 属性为索引;
item(pos):返回位于数字 pos 位置处的节点
text属性
可以通过 nodeValue 属性或 data 属性访问 Text 节点中包含的文本
text属性特点:
1、nodeType 的值为 3;
2、nodeName 的值为"#text";
3、nodeValue 的值为节点所包含的文本;
4、 parentNode 是一个 Element;
5、不支持(没有)子节点。
使用下列方法可以操作节点中的文本:
1、appendData(text):将 text 添加到节点的末尾。
2、deleteData(offset, count):从 offset 指定的位置开始删除 count 个字符。
3、insertData(offset, text):在 offset 指定的位置插入 text。
4、replaceData(offset, count, text):用 text 替换从 offset 指定的位置开始到 offset+
count 为止处的文本。
5、splitText(offset):从 offset 指定的位置将当前文本节点分成两个文本节点。
6、substringData(offset, count):提取从 offset 指定的位置开始到 offset+count 为止处的字符串。
创建文本节点:
document.createTextNode
合并和分割文本节点
1、合并文本节点:如果在一个包含两个或多个文本节点的父元素上调用 normalize()方法,则会将所有文本节点合并成一个节点,结果节点的nodeValue 等于将合并前每个文本节点的 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、分割文本节点:splitText()这个方法会将一个文本节点分成两个文本节点,即按照指定的位置分割 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类型的特点:
1、nodeType 的值为 8;
2、nodeName 的值为"#comment";
3、nodeValue 的值是注释的内容;
4、parentNode 可能是 Document 或 Element;
5、不支持(没有)子节点
Comment 类型与 Text 类型继承自相同的基类,因此它拥有除 splitText()之外的所有字符串操作方法。
CDATASection 类型
CDATASection 类型只针对基于 XML 的文档,表示的是 CDATA 区域。与 Comment 类似,CDATASection 类型继承自 Text 类型,因此拥有除 splitText()之外的所有字符串操作方法。
基本特征:
nodeType 的值为 4;
nodeName 的值为"#cdata-section";
nodeValue 的值是 CDATA 区域中的内容;
parentNode 可能是 Document 或 Element;
不支持(没有)子节点。
DocumentType类型
DocumentType 类型在 Web 浏览器中并不常用,仅有 Firefox、 Safari 和 Opera 支持它,支持 它 的 浏览 器 会 把 DocumentType 对 象 保 存 在 document.doctype 中 。
DOM1 级 描 述 了
DocumentType 对象的 3 个属性: name、 entities 和 notations。其中, name 表示文档类型的名称;entities 是由文档类型描述的实体的 NamedNodeMap 对象; notations 是由文档类型描述的符号的NamedNodeMap 对象。
DocumentFragment类型
DocumentFragment类型是一个比较有用的东西,虽然不能把文档片段直接添加到文档中,但可以将它作为一个“仓库”来使用,即可以在里面保存将来可能会添加到文档中的节点。
例如:如果逐个地添加列表项,将会导致浏览器反复渲染(呈现)新信息。为避免这个问题,可以像下面这样使用一个文档片段来保存创建的列表项,然后再一次性将它们添加到文档中。
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 中不支持(没有)子节点;
6、在 XML 中子节点可以是 Text 或 EntityReference。
document.createAttribute()
开发人员最常使用的是 getAttribute()、 setAttribute()和 remveAttribute()方法,很少直接引用特性节点。
二、DOM操作
动态脚本
考虑到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);
}
动态样式
考虑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);
}
操作表格
操作表格是一个复杂的事情,例如要使用 DOM 来创建下面的 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>
代码过于冗长....
//创建 table
var table = document.createElement("table");
table.border = 1;
table.width = "100%";
//创建 tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
//创建第一行
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);
//创建第二行
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>元素添加了一些属性和方法,使得操作表格相对方便,可以极大地减少代码量。
为<table>元素添加的属性和方法如下:
caption:保存着对<caption>元素(如果有)的指针。
tBodies:是一个<tbody>元素的 HTMLCollection。
tFoot:保存着对<tfoot>元素(如果有)的指针。
tHead:保存着对<thead>元素(如果有)的指针。
rows:是一个表格中所有行的 HTMLCollection。
createTHead():创建<thead>元素,将其放到表格中,返回引用。
createTFoot():创建<tfoot>元素,将其放到表格中,返回引用。
createCaption():创建<caption>元素,将其放到表格中,返回引用。
deleteTHead():删除<thead>元素。
deleteTFoot():删除<tfoot>元素。
deleteCaption():删除<caption>元素。
deleteRow(pos):删除指定位置的行。
insertRow(pos):向 rows 集合中的指定位置插入一行。
为<tbody>元素添加的属性和方法如下:
rows:保存着<tbody>元素中行的 HTMLCollection。
deleteRow(pos):删除指定位置的行。
insertRow(pos):向 rows 集合中的指定位置插入一行,返回对新插入行的引用。
为<tr>元素添加的属性和方法如下:
cells:保存着<tr>元素中单元格的 HTMLCollection。
deleteCell(pos):删除指定位置的单元格。
insertCell(pos):向 cells 集合中的指定位置插入一个单元格,返回对新插入单元格的引用
三、DOM扩展
元素遍历(Element Traversal )
Element Traversal API 为 DOM 元素添加了以下 5 个属性:
childElementCount:返回子元素(不包括文本节点和注释)的个数。
firstElementChild:指向第一个子元素; firstChild 的元素版。
lastElementChild:指向最后一个子元素; lastChild 的元素版。
previousElementSibling:指向前一个同辈元素; previousSibling 的元素版。
nextElementSibling:指向后一个同辈元素; nextSibling 的元素版
HTML5相关扩充
1、 classList 属性
在操作类名时,需要通过 className 属性添加、删除和替换类名。因为 className 中是一个字符串,所以即使只修改字符串一部分,也必须每次都设置整个字符串的值。ClassList可以简化对类名的操作。
add(value):将给定的字符串值添加到列表中。如果值已经存在,就不添加了。
contains(value):表示列表中是否存在给定的值,如果存在则返回 true,否则返回 false。
remove(value):从列表中删除给定的字符串。
toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它
item(index):返回指定的类名
2、焦点
document.activeElement 属性,这个属性始终会引用 DOM 中当前获得了焦点的元素
document.hasFocus()方法,这个方法用于确定文档是否获得了焦点
3、document的变化
document.readyState 属性:
--> loading,正在加载文档;
--> complete,已经加载完文档
document.compatMode属性:这个属性就是为了告诉开发人员浏
览器采用了哪种渲染模式
document.head属性:获取html头
document.charset属性: html字符集
4、自定义数据属性
HTML5规定可以为元素添加非标准的属性,但要添加前缀 data-,目的是为元素提供与渲染无关的信息,或者提供语义信息,使用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;
//设置值
div.dataset.appId = 23456;
div.dataset.myname = "Michael";
5、插入标记
- innerHTML 属性
在读模式下, innerHTML 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的 HTML 标记。
为 innerHTML 设置 HTML 字符串后,浏览器会将这个字符串解析为相应的 DOM树。 - outerHTML 属性
在读模式下, outerHTML 返回调用它的元素及所有子节点的 HTML 标签。在写模式下, outerHTML会根据指定的 HTML 字符串创建新的 DOM 子树然后用这个 DOM 子树完全替换调用元素。 - insertAdjacentHTML()方法
接收两个参数:插入位置和要插入的 HTML 文本。第一个参数必须是下列值之一:
"beforebegin",在当前元素之前插入一个紧邻的同辈元素;
"afterbegin",在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素;
"beforeend",在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素;
"afterend",在当前元素之后插入一个紧邻的同辈元素。
第二个参数是一个 HTML 字符串(与 innerHTML 和 outerHTML的值相同)
//作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");
//作为第一个子元素插入
element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>");
//作为最后一个子元素插入
element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>");
//作为后一个同辈元素插入
element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");
注意:
在插入大量新 HTML 标记时,使用 innerHTML 属性与通过多次 DOM 操作先创建节点再指定它们之间的关系相比,效率要高得多。但是要注意性能问题,不能频繁使用。
四、DOM事件
事件流
“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
事件冒泡:从最内层到最外层
事件捕获:从最外层到最内层
事件处理
“DOM2 级事件” 定义了两个方法,用于处理指定和删除事件处理程序的操作: addEventListener()和 removeEventListener()。用这两个方法就行咯
事件对象
在触发 DOM 上的某个事件时,会产生一个事件对象 event,这个对象中包含着所有与事件有关的信息。
event 对象包含与创建它的特定事件有关的属性和方法:
QQ截图20181108201327.png QQ截图20181108201327.png
网友评论