文章目录
DOM
DOM(文档对象模型)是针对 HTML 和 XML 文档的一个 API(应用程序编程接口)。DOM 脱胎于Netscape 及微软公司创始的 DHTML(动态 HTML),但现在它已经成为表现和操作页面标记的真正的跨平台、语言中立的方式。
10.1 节点层次
DOM 可以将任何 HTML 或 XML 文档描绘成一个由多层节点构成的结构。
<html>
<head>
<title>Smaple</title>
</head>
<body>
<p>hello world</p>
</body>
</html>
10.1.1 Node类型
DOM1 级定义了一个 Node 接口,该接口将由 DOM 中的所有节点类型实现。这个 Node 接口在JavaScript 中是作为 Node 类型实现的;除了 IE 之外,在其他所有浏览器中都可以访问到这个类型。JavaScript 中的所有节点类型都继承自 Node 类型,因此所有节点类型都共享着相同的基本属性和方法。
每个节点都有一个NodeType属性,用于表明节点的类型。
if(someNode.nodeType==Node.ELEMENT_NODE){ //IE 中无效
alert("Node is an element");
}
if(someNode.nodeType==1){ //所以浏览器有效
alert('Node is an element')
}
- nodeName和nodeValue属性
检测元素的类型
if(someNode.nodeType == 1){
value = someNode.nodeName;
}
- 节点关系
每个节点都有一个 childNodes 属性,其中保存着一个 NodeList 对象。 NodeList 是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。NodeList会根据dom结构变化
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
//在 IE8 及之前版本中无效
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
IE8及之前的的将NodeList实现为一个COM对象。因此需要转换IE中的NodeList对象为数组
function convertToArray(nodes){
var array = null;
try{
array = Array.prototype.slice.call(nodes,0); // 针对非IE浏览器
}catch(err){
array = new Array();
for(var i=0;len = nodes.length;i<len;i++){
array.push(nodes[1]);
}
}
return array;
}
每个节点都有parentNode属性,该属性指向文档树中的父节点,通过使用列表中每个节点的 previousSibling和 nextSibling 属性,可以访问同一列表中的其他节点。
if(someNode.nextSibiling===null){
alert("Last Node in the parent's childNode list")
}else if(someNode.previousSibiling == null){
alert("First node in the parent childNode's list")
}
父节点与其第一个和最后一个子节点之间也存在特殊关系。父节点的 firstChild 和 lastChild属性分别指向其 childNodes 列表中的第一个和最后一个节点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k4D0vylR-1577770048115)(/images/JavaScript-DOM-childNodes.jpg)]
所有节点都有的最后一个属性是 ownerDocument,该属性指向表示整个文档的文档节点
3. 操作节点
关系指针只读
- appendChild
- 用于向 childNodes 列表的末尾添加一个节点。添加节点后, childNodes 的新增节点、父节点及以前的最后一个子节点的关系指针都会相应地得到更新。更新完成后, appendChild()返回新增的节点。
var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
//someNode 有多个子节点
var returnedNode = someNode.appendChild(someNode.firstChild);
alert(returnedNode == someNode.firstChild); //false
alert(returnedNode == someNode.lastChild); //true
- insertBefore
- 这个方法接受两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个同胞节点( previousSibling),同时被方法返回
//插入后成为最后一个子节点
returnedNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild); //true
//插入后成为第一个子节点
var returnedNode = someNode.insertBefore(newNode, someNode.firstChild);
alert(returnedNode == newNode); //true
alert(newNode == someNode.firstChild); //true
//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode, someNode.lastChild);
alert(newNode == someNode.childNodes[someNode.childNodes.length-2]); //true
- replaceChild()
- 方法接受的两个参数是:要插入的节点和要替换的节点。要替换的节点将由这个方法返回并从文档树中被移除,同时由要插入的节点占据其位置。
//替换第一个子节点
var returnedNode = someNode.replaceChild(newNode, someNode.firstChild);
//替换最后一个子节点
returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
- removeChild()方法。
- 这个方法接受一个参数,即要移除的节点。被移除的节点将成为方法的返回值,
//移除第一个子节点
var formerFirstChild = someNode.removeChild(someNode.firstChild);
//移除最后一个子节点
var formerLastChild = someNode.removeChild(someNode.lastChild);
- 其他方法
- cloneNode
- 用于创建调用这个方法的节点的一个完全相同的副本。 cloneNode()方法接受一个布尔值参数,表示是否执行深复制。在参数为 true的情况下,执行深复制,也就是复制节点及其整个子节点树;在参数为 false 的情况下,执行浅复制,即只复制节点本身。复制后返回的节点副本属于文档所有,但并没有为它指定父节点。除非通过 appendChild()、 insertBefore()或 replaceChild()将它添加到文档中。
<ul id="myList">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ul>
var mylist = document.getElementById('myList')
var deepList = myList.cloneNode(true);
alert(deepList.childNodes.length); //3
var shallowList = myList.cloneNode(false);
alert(shallowList.childNodes.length); //0
10.1.2 document类型
在浏览器中, document 对象是 HTMLDocument(继承自 Document 类型)的一个实例,表示整个 HTML 页面
- nodeType 的值为 9;
- nodeName 的值为"#document";
- nodeValue 的值为 null;
- parentNode 的值为 null;
- ownerDocument 的值为 null;
- 其子节点可能是一个 DocumentType(最多一个)、 Element(最多一个)、 ProcessingInstruction或 Comment。
Document 类型可以表示 HTML 页面或者其他基于 XML 的文档。
- 文档的子节点
- documenttElement-该属性始终指向 HTML 页面中的"html"元素
- childNodes
<html>
<body>
</body>
</html>
var html = document.documentElement; //取得对<html>的引用
alert(html === document.childNodes[0]); //true
alert(html === document.firstChild); //true
Document 另一个可能的子节点是 DocumentType。
var docuemntType = document.doctype //取得对<!DOCTYPE>的引用
- 文档信息
document 对象还有一些标准的 Document 对象所没有的属性。这些属性提供了 document 对象所表现的网页的一些信息。其中第一个属性就是 title
- title
//取得文档 标题
var originalTree = document.title;
//设置文档标题
document.title = "New Page title"
- URL 属性中包含页面完整的 URL(即地址栏中显示的 URL),
- domain 属性中只包含页面的域名,
- referrer属性中则保存着链接到当前页面的那个页面的 URL。
//取得完整的 URL
var url = document.URL;
//取得域名
var domain = document.domain
//获取来自原页面URL
var referrer = document.referrer
document.domain不能设置不包含的域
document.domain = "example.com"
docuemnt.domain = "example1.com"
document.domain如果先是松散 loose 的不能再设为紧绷的 tight
//假设页面为 lib.example.com
document.domain = "example.com"; //松散的
document.domain = "ftp.example.com" //紧绷的 出错
- 查找元素
- 1.getElementById()
- 接收一个参数:要取得的元素的 ID。如果找到相应的元素则返回该元素,如果不存在带有相应 ID 的元素,则返回 null。注意,这里的 ID 必须与页面中元素的 id特性( attribute)严格匹配,包括大小写。
<div id="myDiv">Some text</div>
var div = document.getElementById("myDiv"); //获取Div 在IE7及以下无用
//返回HTMLDocument对象
- 2.getElementsByTagName()
<img >
var images = document.getElementsByTagName("img");
alert(images.length); //输出图像的数量
alert(images[0].src); //输出第一个图像元素的 src 特性
alert(images.item(0).src); //输出第一个图像元素的 src 特性
* namedItem() 使用这个方法可以通过元素的 name特性取得集合中的项。
<img src="myimage.gif" name="myImage">
var myImage = images.namedItem("myItem")
- 3.getElementsByName - 只有 HTMLDocument 类型才有的方法
这个方法会返回带有给定 name 特性的所有元素。最常使用 getElementsByName()方法的情况是取得单选按钮;
<field>
<legend>Which color do you prefer?</legend>
<ul>
<li><input type="radio" value="red" name="color" id="colorRed">
<label for="colorRed">Red</label></li>
<li><input type="radio" value="green" name="color" id="colorGreen">
<label for="colorGreen">Green</label></li>
<li><input type="radio" value="blue" name="color" id="colorBlue">
<label for="colorBlue">Blue</label></li>
</ul>
</field>
var radios = document.getElementssByName("color");
- 特殊集合
document 对象还有一些特殊的集合。这些集合都是 HTMLCollection 对象,为访问文档常用的部分提供了快捷方式
- document.anchors,包含文档中所有带 name 特性的元素;
- document.applets,包含文档中所有的元素,因为不再推荐使用/applet>元素,
所以这个集合已经不建议使用了; - document.forms, 包含文档中所有的元素, 与 document.getElementsByTagName(“form”)
得到的结果相同; - document.images,包含文档中所有的元素,与 document.getElementsByTagName
(“img”)得到的结果相同; - document.links,包含文档中所有带 href 特性的元素。
- DOM一致性检测
document.implementation 属性就是为此提供相应信息和功能的对象,与浏览器对 DOM 的实现直接对应。 DOM1 级只为 document.implementation 规定了一个方法,即 hasFeature()
var hasXmlDom = document.implementation.hasFeature("XML", "1.0");
- 文档写入
- write
- 原样写入
- writeln
- 在文档末尾添加 换行符 \n
- open
- close
<html>
<head>
<title>document.write() Example 2</title>
</head>
<body>
<script type="text/javascript">
document.write("<script type=\"text/javascript\" src=\"file.js\">" +
"<\/script>"); //避免<script>被解释为与外部的<script>标签匹配 加入转义字符
</script>
</body>
</html>
10.1.3 Element类型
Element 类型用于表现 XML 或 HTML 元素,提供了对元素标签名、子节点及特性的访问
- nodeType 的值为 1;
- nodeName 的值为元素的标签名;
- nodeValue 的值为 null;
- parentNode 可能是 Document 或 Element;
- 其子节点可能是 Element、 Text、 Comment、 ProcessingInstruction、 CDATASection 或
EntityReference。
<div id="myDiv"></div>
var div = document.getElementById("myDiv");
alert(div.tagName); //"DIV" 大写
alert(div.tagName == div.nodeName); //true
- HTML元素
HTMLElement 类型直接继承自 Element 并添加了一些属性。添加的这些属性分别对应于每个 HTML元素中都存在的下列标准特性。
- id,元素在文档中的唯一标识符。
- title,有关元素的附加说明信息,一般通过工具提示条显示出来。
- lang,元素内容的语言代码,很少使用。
- dir,语言的方向,值为"ltr"( left-to-right,从左至右)或"rtl"( right-to-left,从右至左),也很少使用。
- className,与元素的 class 特性对应,即为元素指定的 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"
- 取得特性
每个元素都有一或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的DOM 方法主要有三个,分别是 getAttribute()、 setAttribute()和 removeAttribute()
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()对应的方法是 setAttribute(),这个方法接受两个参数:要设置的特性名和值。如果特性已经存在,setAttribute()会以指定的值替换现有的值;如果特性不存在, setAttribute()则创建该属性并设置相应的值。
div.setAttribute("id", "someOtherId");
div.setAttribute("class", "ft");
div.setAttribute("title", "Some other text");
div.setAttribute("lang","fr");
div.setAttribute("dir", "rtl");
removeAttribute(),这个方法用于彻底删除元素的特性。调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性
div.removeAttribute("class");
- attributes属性
Element 类型是使用 attributes 属性的唯一一个 DOM 节点类型。 attributes 属性中包含一个NamedNodeMap,与NodeList 类似,也是一个“动态”的集合
* getNamedItem(name):返回 nodeName 属性等于 name 的节点;
* removeNamedItem(name):从列表中移除 nodeName 属性等于 name 的节点;
* setNamedItem(node):向列表中添加节点,以节点的 nodeName 属性为索引;
* item(pos):返回位于数字 pos 位置处的节点。
///要取得元素的 id 特性,可以使用以下代码。
var id = element.attributes.getNamedItem("id").nodeValue;
//将其 nodeValue 设置为新值
element.getAttributes["id"].nodeValue = "someOtherId";
//setNamedItem()这个方法可以为元素添加一个新特性
element.attributes.setNamedItem(newAttr);
遍历元素
function outputAttributes(element){
var pairs = new Array(),
attrName,
attrValue,
i,
len;
for(i=0;len=element.attributes.length;i<len;i++){
attrName = element.attribute[i].nodeName;
attrValue = element.attribute[i].nodeValue;
pairs.push(attrName+"=\"+attrValue+"\");
}
return pairs.join(" ");
}
只返回特定的元素
function outputAttribute(element){
var pairs = new Array(),
attrName,
attrValue,
i,
len;
for(i=0;len=element.attributes.length;i<len;i++){
attrName = element.attribute[i].nodeName;
attrValue = element.attribute[i].nodeValue;
if(element.attributes[i].specified){
pairs.push(attrName+"=\"+attrValue+"\");
}
}
return pairs.join(" ");
}
- 创建元素
使用 document.createElement()方法可以创建新元素。这个方法只接受一个参数,即要创建元素的标签名。这个标签名在 HTML 文档中不区分大小写,而在 XML(包括 XHTML)文档中,则是区分大小写的。
var div = document.createElement("div");
div.id = "myNewDiv";
div.className = "box";
要把新元素添加到文档树,可以使用 appendChild()、 insertBefore()或 replaceChild()方法。
document.body.appendChild(div);
//使用 createElement(),即为这个方法传入完整的元素标签,也可以包含属性
var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >");
<=IE7时 创建某些元素
- 动态设置iframe的name特性
- 不能通过表单的reset()方法重设动态创建input元素
- 动态创建type特性值为reset的button元素
- 创建一批name相同的按钮
if (client.browser.ie && client.browser.ie <=7){
//创建一个带 name 特性的 iframe 元素
var iframe = document.createElement("<iframe name=\"myframe\"></iframe>");
//创建 input 元素
var input = document.createElement("<input type=\"checkbox\">");
//创建 button 元素
var button = document.createElement("<button type=\"reset\"></button>");
//创建单选按钮
var radio1 = document.createElement("<input type=\"radio\" name=\"choice\" "+"value=\"1\">");
var radio2 = document.createElement("<input type=\"radio\" name=\"choice\" "+"value=\"2\">");
}
- 元素的子节点
元素可以有任意数目的子节点和后代节点,因为元素可以是其他元素的子节点。元素的childNodes属性中包含了它的所有子节点,这些子节点有可能是元素、文本节点、注释或处理指令。
<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
for(var i=0,len=element.childNodes.length;i<len;i++){
if(element.childNodes[i].nodeType==1){
//执行某些操作
}
}
var ul = document.getElementById("myList");
var items = ul.getElementsByTagName("li");
10.1.4 text类型
Text 节点具有以下特征:
- nodeType 的值为 3;
- nodeName 的值为"#text";
- nodeValue 的值为节点所包含的文本;
- parentNode 是一个 Element;
- 不支持(没有)子节点
nodeValue修改 - appendData(text):将 text 添加到节点的末尾。
- deleteData(offset, count):从 offset 指定的位置开始删除 count 个字符。
- insertData(offset, text):在 offset 指定的位置插入 text。
- replaceData(offset, count, text):用 text 替换从 offset 指定的位置开始到 offset+
count 为止处的文本。 - splitText(offset):从 offset 指定的位置将当前文本节点分成两个文本节点。
- substringData(offset, count):提取从 offset 指定的位置开始到 offset+count 为止处的字符串。
- 创建文本节点
可以使用 document.createTextNode()创建新文本节点,这个方法接受一个参数——要插入节点中的文本
var textNode = document.createTextNode("<strong>Hello</strong> world!");
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world!");
element.appendChild(textNode);
document.body.appendChild(element);
//包含多个文本节点
var element = document.createElement("div");
element.className = "message";
var textNode = document.createTextNode("Hello world");
element.appendCild(textNode);
var anotherTextNode = document.createTextNode("Yippeee");
element.body.appendChild(element);
- 规范化文本节点
这个方法是由 Node 类型定义的(因而在所有节点类型中都存在),名叫 normalize()
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!"
- 分割文本节点
Text 类型提供了一个作用与 normalize()相反的方法: 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
10.1.5 Comment类型
注释在 DOM 中是通过 Comment 类型来表示的。 Comment 节点具有下列特征:
- nodeType 的值为 8;
- nodeName 的值为"#comment";
- nodeValue 的值是注释的内容;
- parentNode 可能是 Document 或 Element;
- 不支持(没有)子节点
<div id="myDiv"><!--A comment --></div>
var div = document.getElementById("myDiv");
var comment = div.firstChild;
alert(comment.data); //"A comment"
var comment = document.createComment("A comment ");
10.1.6 CDATASection类型
CDATASection 类型只针对基于 XML 的文档,表示的是 CDATA 区域。
- nodeType 的值为 4;
- nodeName 的值为"#cdata-section";
- nodeValue 的值是 CDATA 区域中的内容;
- parentNode 可能是 Document 或 Element;
- 不支持(没有)子节点。
CDATA 区域只会出现在 XML 文档中,因此多数浏览器都会把 CDATA 区域错误地解析为 Comment或 Element。以下面的代码为例:
<div id="myDiv"><![CDATA[This is some content.]]></div>
10.1.7 DocumentType类型
它具有下列特征:
- nodeType 的值为 10;
- nodeName 的值为 doctype 的名称;
- nodeValue 的值为 null;
- parentNode 是 Document;
- 不支持(没有)子节点。
严格型 HTML4.01 的文档类型声明为例:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
DocumentType 的 name 属性中保存的就是"HTML":
alert(document.doctype.name); //"HTML"
10.1.8 DocumentFragment类型
DocumentFragment 节点具有下列特征:
- nodeType 的值为 11;
- nodeName 的值为"#document-fragment";
- nodeValue 的值为 null;
- parentNode 的值为 null;
- 子节点可以是 Element、 ProcessingInstruction、 Comment、 Text、 CDATASection 或EntityReference。
- 创建文档片段
<ul id="myList"></ul>
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);
10.1.9 Attr类型
特性节点具有下列特征:
- nodeType 的值为 2;
- nodeName 的值是特性的名称;
- nodeValue 的值是特性的值;
- parentNode 的值为 null;
- 在 HTML 中不支持(没有)子节点;
- 在 XML 中子节点可以是 Text 或 EntityReference。
要为元素添加 align 特性,可以使用下列代码:
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"
10.2 DOM操作技术
10.2.1 动态脚本
- 使用<script>元素可以向页面中插入 JavaScript 代码
- 一种方式是通过其 src 特性包含外部文件
- 另一种方式就是用这个元素本身来包含代码。
<sript type="text/javascript" src="client.js"></script>
var script = document.createElement("script");
script.type = "text/javascript";
script.scr="client.js";
document.body.appendChild(script);
封装加载脚本的函数
function loadScript(){
var script = document.createElement("script");
script.type = "text/script";
script.src = url;
document.appendChildd(script);
}
- 行内JavaScript代码
<script type ="text/javascript">
function sayHi(){
alert("hi")
}
</script>
大多数浏览器可以使用如下代码实现上述代码
var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode("function sayHi(){alert('hi');}"));
document.body.appendChild(script);
IE下可以使用如下代码:IE 将<script>视为一个特殊的元素,不允许 DOM 访问其子节点
var script = document.createElement("script");
script.type = "text/javascript";
script.text = "function sayHi(){alert('hi');}";
document.body.appendChild(script);
最后总的代码如下:
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');}");
10.2.1 动态样式
能够把 CSS 样式包含到 HTML 页面中的元素有两个。其中, <link>元素用于包含来自外部的文件,而<style>元素用于指定嵌入的样式。与动态脚本类似,所谓动态样式是指在页面刚加载时不存在的样式;动态样式是在页面加载完成后动态添加到页面中的。
<link rel="stylesheet" type="text/css" href="styles.css">
使用 DOM 代码可以很容易地动态创建出这个元素:
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "style.css";
var head = document.getElementsByTagName("head")[0];
head.appendChild(link);
加载style元素
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);
}
- 内部样式
<style type="text/css">
body {
background-color: red;
}
</style>
style和script类型,用一下函数解决
function loadStyleString(css){
var style = document.createElement("style");
style.type = "text/css";
try{
style.appendChild(document.createTextNode(css));
}catch{
style.styleSheet.cssText = css;
}
var head = document.getElementsByTagNames("head")[0];
head.appendChild(style);
}
10.2.3 操作表格
<table>元素是 HTML 中最复杂的结构之一。要想创建表格,一般都必须涉及表示表格行、 单元格、表头等方面的标签。
<table>
<tbody>
<tr>
<td>Cell 1,1</td>
<td>Cell 1,2</td>
</tr>
<tr>
<td>Cell 2,1</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);
重写代码
//创建 table
var table = document.createElement("table");
table.border = 1;
table.width = "100%";
//创建 tbody
var tbody = document.createElement("tbody");
table.appendChild(tbody);
//创建第一行
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"));
//创建第二行
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);
10.2.4 使用NodeList
所有 NodeList 对象都是在访问 DOM 文档时实时运行的查询。
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);
}
一般来说,应该尽量减少访问 NodeList 的次数。因为每次访问 NodeList,都会运行一次基于文档的查询。所以,可以考虑将从 NodeList 中取得的值缓存起来。
10.3
DOM 是语言中立的 API,用于访问和操作 HTML 和 XML 文档。 DOM1 级将 HTML 和 XML 文档形象地看作一个层次化的节点树,可以使用 JavaScript 来操作这个节点树,进而改变底层文档的外观和结构。
DOM 由各种节点构成,简要总结如下。
- 最基本的节点类型是 Node,用于抽象地表示文档中一个独立的部分;所有其他类型都继承自
Node。 - Document 类型表示整个文档,是一组分层节点的根节点。在 JavaScript 中, document 对象是
Document 的一个实例。使用 document 对象,有很多种方式可以查询和取得节点。 - Element 节点表示文档中的所有 HTML 或 XML 元素,可以用来操作这些元素的内容和特性。
- 另外还有一些节点类型,分别表示文本内容、注释、文档类型、 CDATA 区域和文档片段。
::: danger
减少dom操作
:::