几个概念:
DOM:文档对象模型,是针对 HTML 和 XML 文档的一个 API(应用程序编程接口)。
根节点:就是 Document 节点。
nodeType: 所有节点的属性,用于表明节点的类型。
DOM1 级的接口,该接口除了 IE 之外,在其他所有浏览器中都可以访问到这个类型。
节点类型由在 Node 类型中定义的下列 12 个数值常量来表示,任何节点类型必居其一:
Node.ELEMENT_NODE;
Node.ATTRIBUTE_NODE;
Node.TEXT_NODE;
Node.CDATA_SECTION_NODE;
Node.ENTITY_REFERENCE_NODE;
Node.ENTITY_NODE;
Node.PROCESSING_INSTRUCTION_NODE;
Node.COMMENT_NODE;
Node.DOCUMENT_NODE;
Node.DOCUMENT_TYPE_NODE;
11. Node.DOCUMENT_FRAGMENT_NODE;12. Node.NOTATION_NODE;
分别返回 1-12 数值。
如:
<h1 id="h1">hello this is h1</h1> <h2 id="h2">hello this is h2</h2> <p id="p">this is a paragraph<img id="img" alt="none......"></p> console.log(document.getElementById("h1").nodeType == Node.ELEMENT_NODE); //true
因为 IE 兼容性问题,Node 类型的构造函数无效,最好还是将它换成数字值进行比较。如:
console.log(document.getElementById("h1").nodeType == 1); //true
nodeName
和 nodeValue
属性 在使用这两个属性之前,最好是先检测一下节点的类型:
if (someNode.nodeValue == 1){ value = someNode.nodeName; } <input id="input" type="text" name="textInput" value="this is an input"> console.log(document.getElementById("input").nodeName); //INPUT console.log(document.getElementById("input").nodeValue); //null
childNodes
属性和 NodeList
对象和它的 item()
方法 前者中保存着一个 NodeList 对象;
可以通过方括号和 item() 方法来访问在后者的节点;
如:
<p id="p">this is a paragraph<img id="img" alt="none......"></p> var para = document.getElementById("p"); var array = Array.prototype.slice.call(para.childNodes,0); console.log(array);
上述代码在 IE8 中无效,因为 IE8 及更早版本将 NodeList 实现为一个 COM 对象。但下面的代码可以在所有浏览器中运行:
function convertToArray(nodes){ var array = null; try{ array = Array.prototype.slice.call(nodes,0); }catch(ex){ array = new Array(); for (var i=0; i<nodes.length; i++){ array.push(nodes[i]); } } return array; }
parentNode
属性和 previousSibling
、 nextSibling
属性 parentNode
属性指向文档树中的父节点;同胞节点中第一个节点的 previousSibling
属性的值为null;同理最后一个节点的 nextSibling
属性的值也为null。如:
if (someNode.nextSibling === null){ console.log("last node in the parent's childNodes list."); } else if(someNode.previousSibling === null){ console.log("first node in the parent's childNodes list."); }
firstChild
属性和 lastChild
属性 这两个属性分别等于: someNode.childNodes[0]
和 someNode.childNodes[someNode.childNodes.length - 1];
hasChildNodes()
方法和 ownerDocument
属性 前者返回是否包含子节点的布尔值;后者指向表示整个文档的文档节点。
<h1 id="h1">hello this is h1</h1> var title = document.getElementById("h1"); console.log(title.childNodes) //["hello this is h1"] <h1 id="h1">hello this is h1</h1> var title = document.getElementById("h1"); console.log(title.ownerDocument.nodeType) //9
以下述代码为例:
<p id="p">this is a paragraph<img id="img" alt="none......"></p>
appendChild()
方法 该方法用于向 childNodes 列表的末尾添加一个节点。其中,如果在 调用 appendChild() 时传入了父节点的第一个子节点,那么该节点就会成为父节点的最后一个子节点,如:
var txt = document.getElementById("p"); txt.appendChild(txt.firstChild); console.log(txt.childNodes) //[<img id="img" alt="none......">, "this is a paragraph"]
insertBefore()
方法 用于把节点放在 childNodes 列表中某个特定的位置上。接收两个参数:要插入的节点和作为参照的节点,如:
var txt = document.getElementById("p"); var newNode = document.createElement("p"); var newNode_value = document.createTextNode("hello there"); newNode.appendChild(newNode_value); txt.insertBefore(newNode, txt.lastChild); document.write(Array.prototype.slice.call(txt.childNodes,0));//[object Text],[object HTMLParagraphElement],[object HTMLImageElement]
如果参照节点为 null,则 insertBefore() 与 appendChild() 执行相同的操作。
replaceChild()
方法 该方法接收两个参数:要插入的节点和要替换的节点,如:
var txt = document.getElementById("p"); var newNode = document.createElement("p"); var newNode_value = document.createTextNode("hello there"); newNode.appendChild(newNode_value); txt.replaceChild(newNode, txt.lastChild); document.write(Array.prototype.slice.call(txt.childNodes,0));//[object Text],[object HTMLParagraphElement]
removeChild()
方法 该方法接收一个参数:要删除的节点,如:
var txt = document.getElementById("p"); txt.removeChild(txt.lastChild); document.write(Array.prototype.slice.call(txt.childNodes,0));//[object Text]
cloneNode()
方法 该方法所有类型节点都具有;用于创建调用这个方法的节点的一个完全相同的副本。接收一个参数,表示是否执行深赋值。true 执行深复制,复制节点及整个子节点树;false 执行浅复制,只复制节点本身,后要通过 appendChild() 等方法添加到文档中。如:
<ul id="unordered"> <li>item 1</li> <li>item 2</li> <li>item 3</li> </ul> var myList = document.getElementById("unordered"); var deepList = myList.cloneNode(true); console.log(deepList.childNodes.length); //7 (IE < 9 版本情况下为3,因为不会创建空白符节点。) var shallowList = myList.cloneNode(false); console.log(shallowList.childNodes.length); //0
normalize()
方法 该方法的作用是处理文档树中的文本节点。在出现文本节点不包含文本,或者连接出现两个文本节点的情况下,就删除它。
JavaScript 通过 Document 类型表示文档,在浏览器中,document 对象是 HTMLDocument 的一个实例,表示整个 HTML 页面。Document 节点具有以下特征:
console.log(document.nodeType + document.nodeName + document.nodeValue + document.parentNode + document.ownerDocument); //9#documentnullnullnull
以及其子节点可能是一个 DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction 或 Comment。
documentElement
属性和 body
属性 其子节点可能是一个 DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction 或 Comment。但还有两个内置的访问其子节点的方式:一个是 documentElement 属性,该属性始终指向 <html>
元素如:
var html = document.getElementsByTagName("html")[0]; console.log(document.documentElement === html); //true var html = document.firstChild; console.log(document.documentElement === html); //true var html = document.childNodes[0]; console.log(document.documentElement === html); //true
以上代码建立在如下网页源代码之上:
<html> <head> </head> <body> <script> var html = document.childNodes[0]; console.log(document.documentElement === html); //true </script> </body> </html>
另外一个则是 body 属性。直接指向 <body>
元素。
DocumentType
即 doctype
属性 通常将 <!DOCTYPE> 标签看成一个与文档其他部分不同的实体,可以通过 doctype 属性(document.doctype)查看。如:
<!doctype html> <html> <head> </head> <body> <script> console.log(document.doctype); //<!DOCTYPE html> </script> </body> </html>
浏览器对 document.doctype 的支持差别很大,主要有:
IE8 及之前的版本:当做注释,document.doctype 的值为 null;
IE9+ 及 Firefox:作为第一个子节点;
Safari、Chrome 和 Opera:不作为文档的子节点。
另外,按理说出现在 html 标签之外的注释也算是文档的子节点。如:
<!--第一个注释--> <html> <head> </head> <body> </body> </html> <!--第二个注释-->
浏览器在处理位于 html 标签之外的注释方面存在如下差异:
IE8 及之前的版本、Safari 3.1 及更高的版本、Opera 和 Chrome 只为第一条注释创建节点;
IE9 及更高的版本将两个注释都创建为节点;
Firefox、Safari 3.1 之前的版本会忽略这两个注释。
title
属性 document 对象的另一个属性是 title,包含这 title 元素中的文本,但是修改 title 属性的值并不会改变 title 标签元素。如:
var x = setTimeout(setTitle, 1000); function setTitle(){ document.title = "Hello"; var y = setTimeout(setTitle2, 1000); function setTitle2(){ document.title = "World"; x = setTimeout(setTitle, 1000); } }
以上代码可以以1秒的速度自动切换显示 title 标签的内容
URL
、 domain
和 referrer
属性 三者分别包含完整的 URL;页面的域名以及连接到当前页面的那个页面的 URL。三个属性当中只有 domain 是可以设置的。如:
//假设页面来自 p2p.wrox.com 域 document.domain = "wrox.com"; //成功 document.domain = "baidu.com"; //失败
另外,由于跨域安全限制,来自不同的子域的页面无法通过 js 通信。还有,如果域名一开始是“松散的”(loose),那么就不能再设置为“紧绷的”(tight)。即将 document.domain 设置为"wrox.com"之后,就不能再将其设置回"p2p.wrox.com"否则将出错。
getElementById()
方法 该方法接收一个参数即元素的 ID。以下面的元素为例:
<div id="myDiv">Some text</div>
可以使用下面的代码取得这个元素:
var div = document.getElementById("myDiv"); var div = document.getElementById("mydiv"); //无效的ID 但是可以在 IE7 及更早的版本中使用
如果文档中出现多个 ID 相同的元素,则取得第一次出现的那个。
IE7 及更早的版本在 name 特性与给定的 ID 匹配的表单元素(input textarea button select)也会被该方法访问。如:
<input type="text" name="myElement" value="hello"> <div id="myElement">Some text</div> console.log(document.getElementById("myElement"));
所以最好不要把 id 与 name 设置成同一个名称。
getElementsByTagName()
方法、 HTMLCollection
属性以及 namedItem()
方法 前者接收一个参数即要去的的元素的标签名,后者则是该方法返回的对象,如下代码将取得所有 img 元素,并返回一个 HTMLCollection 对象:
<img src="" alt=""> <img src="" alt=""> <img src="" alt=""> <img src="" alt=""> console.log(document.getElementsByTagName("img").length); //4
这里返回的 HTMLCollection 对象可以通过方括号语法或 item() 方法来访问:
<body> <img src="" alt=""> <img src="pics/topics.png" height="104" width="410" alt=""> <img src="" alt=""> <img src="" alt=""> <script> var images = document.getElementsByTagName("img"); console.log(images.length); console.log(images[1].src); //获取src console.log(images.item(1).src); //获取src </script> </body>
另外,可以通过 namedItem()
方法来获得指定的 name 特性的项如:
<body> <img src="" alt=""> <img src="pics/topics.png" height="104" width="410" alt="" name="secImg"> <script> var images = document.getElementsByTagName("img"); console.log(images.namedItem("secImg").src); //获取了name特性为secImg的img标签的src </script> </body>
当然也可以使用方括号语法:
<body> <img src="" alt=""> <img src="pics/topics.png" height="104" width="410" alt="" name="secImg"> <script> var images = document.getElementsByTagName("img"); console.log(images.namedItem("secImg").src); //获取了name特性为secImg的img标签的src console.log(images["secImg"].src); //与上面的相同 </script> </body>
在后台,对数值索引就会调用 item(),而对字符串索引就会调用 namedItem()。
另外,可以向 getElementsByTagName() 中传入“*”。表示全部标签;
getElementsByName()
方法 该方法返回给定 name 特性的所有元素。最常用的情况是取得单选按钮。
<body> <fieldset> <legent>Which color do you perfer?</legent> <ul> <li> <input type="radio" name="color" value="red" id="colorRed"> <label for="">Red</label> </li> <li> <input type="radio" name="color" value="green" id="colorGreen"> <label for="">Green</label> </li> <li> <input type="radio" name="color" value="blue" id="colorBlue"> <label for="">Blue</label> </li> </ul> </fieldset> <script> var radios = document.getElementsByName("color"); console.log(radios[2].value); //blue </script> </body>
在这里 namedItem() 方法只会取得第一项,因为每一项的 name 特性都是 color。
document.anchors:文档中所有带 name 特性的 a 元素;
document.forms:文档中所有 img 元素
document.links:文档中所有带 href 特性的 a 元素;
如下:
<form action=""></form> <form action=""></form> <img src="" alt=""> <a href="#">abc</a> <a name="noName" href="#">abc</a> <a name="noName" href="#">abc</a> console.log(document.anchors.length); //2 console.log(document.forms.length); //2 console.log(document.links.length); //3
document.implementation
属性与 hasFeature()
方法 由于 DOM 有多个级别,包含多个部分,因此检测浏览器实现了 DOM 的哪些部分是非必要。该方法接收两个参数:要检测的 DOM 功能的名称及版本号。如果浏览器支持,则返回 true,如:
console.log(document.implementation.hasFeature("XML", "1.0")); //True
列表如下:
Core 实现 Node、Element、Document、Text 和其他所有DOM实现都要求实现的基本接口 所有遵守 DOM 标准的实现都必须支持该模块。 HTML 实现 HTMLElement、HTMLDocument 和其他 HTML 专有接口。 XML 实现 Entity、EntityReference、ProcessingInstruction、Notation 和其他 XML 文档专用的节点类型。 StyleSheets 实现描述普通样式表的简单接口。 CSS 实现 CSS 样式表专有的接口。 CSS2 实现 CSS2Properties 接口。 Events 实现基本的事件处理接口。 UIEvents 实现处理用户界面事件的接口。 MouseEvents 实现处理鼠标事件的接口。 HTMLEvents 实现处理 HTML 事件的接口。 MutationEvents 实现处理文档变化事件的接口。 Range 实现操作文档范围的接口。 Traversal 实现进行高级文档遍历的接口。 Views 实现处理文档视图的接口。
write()
、 writeln()
、 open()
以及 close()
其中,writeln() 会在字符串最后添加一个换行符(/n)如:
document.write("hello"); document.writeln("there"); //最后面有个换行符 document.write("anybodyHome?"); //hellothere anybodyHome?
此外,还可以使用 write() 和 writeln() 方法动态地包含外部资源。
需要注意的是,如果在文档加载完毕后再执行 document.write 则会重写文档。
方法 open() 和 close() 分别用于打开和关闭网页的输出流。
该类型用于表现 XML 或 HTML 元素,提供了对元素标签名、子节点及特性的访问。主要特性如下:
var x = document.getElementsByTagName("p")[0]; console.log(x.tagName); //P console.log(x.nodeName); //P console.log(x.nodeType); //1 console.log(x.nodeValue); //null console.log(x.parentNode); //HTMLDivElement
其子节点可能是 Element、Text、Comment、ProcessingInstruction、CDATASection 或 EntityReference。
因为 XML 和 HTML 的标签名大小写关系,在比较标签名的时候最好先转换成小写,如:
var x = document.getElementsByTagName("p")[0]; if (x.tagName === "p") { console.log('testing1'); }; if (x.tagName.toLowerCase() === "p") { console.log('testing2'); }; //testing2
所有 HTML 元素都由 HTMLElement 类型表示,标准特性如下:
id:元素的唯一标识符;
title:附加说明信息;
lang:语言代码;
dir:语言方向;
className:元素的 class 特性对应,即 CSS 类。
如:
<div id="bd" class="myDiv" title="Body text" lang="en" dir="ltr"></div> var div = document.getElementById("bd"); console.log(bd.dir); //ltr
另外还有其他众多 HTML 元素以及与之关联的类型。这里不再累述。
getAttribute()
方法 该方法主要是取得特性的值;
需要注意的是,任何元素的所有特性,都可以通过 DOM 元素本身的属性来访问。但是自定义的特性不会以属性的形式添加到 DOM 对象中。如:
<div id="bd" my="hello" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); console.log(div.my); //undefined(IE 除外) </script>
由于各种原因,应该只有在取得自定义特性值的情况下,才会使用该方法,如:
<div id="bd" my="hello" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); console.log(div.my); //undefined(IE 除外) console.log(div.getAttribute("my")); //应该用getAttribute方法访问自定义特性 </script>
另外需要注意的是,根据 HTML5 规范,自定义特性应该加上 data- 前缀以便验证,如:
<div id="bd" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); div.setAttribute("data-my_attr", "value"); console.log(div.getAttribute("data-my_attr")); //value console.log(div.attributes[5].name); //data-my_attr </script>
setAttribute()
方法 该方法接收两个参数:要设置的特性名和值。如果特性名存在,则执行替换操作。如:
<div id="bd" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); div.my = "hello"; console.log(div.getAttribute("my")); //null console.log(div.my); //hello </script>
综上所述,在取得特性值的情况下,最好用 getAttribute()
方法取得自定义特性,用 DOM 属性访问公认的特性;在设置特性值的情况下,最好用 DOM 属性来设置公认的特性,用 setAttribute()
方法设置自定义特性。如:
<div id="bd" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); div.my = "value1"; console.log(div.my); //value1 console.log(div.getAttribute("my")); //null div.setAttribute("my2", "value2"); console.log(div.my2); //undefined console.log(div.getAttribute("my2")); //value2 </script>
removeAttribute()
方法 一个参数,IE6 及以前的版本不支持该方法。如:
<div id="bd" class="myDiv" title="Body text" lang="en" dir="ltr"></div> <script> var div = document.getElementById("bd"); div.my = "hello"; console.log(div.my); div.removeAttribute("my"); console.log(div.my); div.setAttribute("my2", "value"); console.log(div.getAttribute("my2")); div.removeAttribute("my2"); console.log(div.getAttribute("my2")); //null </script>
该属性包含一个 NamedNodeMap 对象,该对象有下列方法(不常用):
getNamedItem(Name):返回 nodeName 属性等于 Name 的节点;
removeNamedItem(Name):移除指定的节点;
setNamedItem(Node):添加指定的节点;
item(pos):返回位于数字 pos 位置的节点;
具体如下:
<div id="divId"> <p id="pId">hhh</p> </div> var pId = document.getElementById("pId"); var namedItem = pId.attributes.getNamedItem("id").nodeValue; console.log(namedItem); //pId var attrList = pId.attributes.item(0).nodeValue; //pId console.log(attrList); pId.attributes.removeNamedItem("id"); console.log(pId.id); //
该属性经常涌来遍历元素的特性,如:
<p id="pId" name="para">hhh</p> var pElem = document.getElementById("pId"); function outputAttributes(element) { var pairs = new Array(); var attrName, attrValue, i, len; for (i = 0, len = element.attributes.length; i < len; i++) { attrName = element.attributes[i].nodeName; attrValue = element.attributes[i].nodeValue; pairs.push(attrName + "=/"" + attrValue + "/""); } return pairs.join(" "); } console.log(outputAttributes(pElem)); //id="pId" name="para"
但是需要强调的是:
不通浏览器返回的顺序不通;
IE7 及更早的版本会返回 HTML 元素中所有可能的特性,包括没有指定的特性
每个特性节点都有一个名为 specified 的属性,这个属性的值如果为 true,则意味着要么是在 HTML 中制定了相应特性,要么是通过 setAttribute() 方法设置了该特性。
上面的代码兼容性考虑,应该改为下面这样:
<p id="pId" name="para">hhh</p> var pElem = document.getElementById("pId"); function outputAttributes(element) { var pairs = new Array(); var 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(" "); } console.log(outputAttributes(pElem)); //id="pId" name="para"
createElement()
方法 该方法接收一个参数,即要创建元素的标签名。用该方法创建的新元素被赋予了 ownerDocument
属性。随后通过 appendChild()
等方法添加到文档树中。如:
var newElementP = document.createElement("p"); var newElementPValue = document.createTextNode("data"); newElementP.title = "im title"; newElementP.appendChild(newElementPValue); document.body.appendChild(newElementP); console.log(newElementP.lastChild.nodeValue); //data console.log(newElementP.title); //im title
在 IE 中可以用另一种方式使用 createElement(),即为这个方法传入完整的元素标签,也可以包含属性,但这种方法存在很多问题,不建议使用。(具体见《js高级程序设计》第十章节点层次 Element 类型)
以下面代码为例:
<ul id="ulList"> <li>1</li> <li>2</li> <li>3</li> </ul> var list = document.getElementById("ulList"); var childNodesList = list.childNodes; console.log(childNodesList.length); //7 for (var i = childNodesList.length - 1; i >= 0; i--) { if (childNodesList[i].nodeType == 1) { console.log(childNodesList[i].nodeName); //LI*3 }; }; for (var i = childNodesList.length - 1; i >= 0; i--) { if (childNodesList[i].nodeType == 3) { document.write(childNodesList[i].nodeValue); //LI*3的text节点值1、2、3 }; };
如同上面的代码一样,如果需要通过 childNodes 属性遍历子节点,呢么一定要在操作以前检查 nodeType 属性。因为不同的浏览器会返回不同的节点个数:
<ul id="ulList"><li>1</li><li>2</li><li>3</li></ul>
这里才会返回 childNodesList.length 为3。
如果要返回上面代码中的所有 li 元素,可以使用如下代码:
var ulList = document.getElementById("ulList"); var liList = ulList.getElementsByTagName("li"); console.log(liList.length); //3
要注意的是,字符串会经过 HTML 或 XML 编码。如:
var pElem = document.getElementById("pId"); pElem.firstChild.nodeValue = "<p>hello there</p>"; console.log(pElem.innerHTML); //<p>hello there</p>
createTextNode()
方法 该方法创建文本节点,接收一个参数即文本字符串。按理说一个元素只有一个文本节点,但是如果为其赋予了多个节点,那么这些节点中的文本就会连起来,并且中间没有空格。如:
var newP = document.createElement("p"); var newPValue = document.createTextNode("data"); newP.appendChild(newPValue); document.body.appendChild(newP); var anotherPValue = document.createTextNode("anotherData"); newP.appendChild(anotherPValue); //dataanotherData
normalize()
方法 该方法在一个包含两个或多个文本节点的父元素上调用,将会把所有文本节点合成成一个节点。如:
var newP = document.createElement("p"); var newPValue = document.createTextNode("data"); newP.appendChild(newPValue); document.body.appendChild(newP); var anotherPValue = document.createTextNode("anotherData"); newP.appendChild(anotherPValue); //dataanotherData console.log(newP.childNodes.length); //2 newP.normalize(); console.log(newP.childNodes.length); //1
splitText()
方法 这个方法将一个文本节点分成两个文本节点,原来的文本节点包含从开始到指定位置之前的内容;新的文本节点将包含剩下的文本。这个方法会返回一个新文本节点。如:
var newP = document.createElement("p"); var newPValue = document.createTextNode("data"); newP.appendChild(newPValue); document.body.appendChild(newP); var anotherPValue = document.createTextNode("anotherData"); newP.appendChild(anotherPValue); //dataanotherData newP.normalize(); var anotherNewP = newP.firstChild.splitText(4); console.log(newP.firstChild.nodeValue); //data console.log(newP.lastChild.nodeValue); //anotherData newP.normalize(); console.log(newP.firstChild.nodeValue); //dataanotherData
createComment()
方法 该方法可以创建注释节点。不过鲜有人使用。拥有除 splitText() 之外的所有字符串操作方法。
该类型只有在真正的 XML 文档中可以使用以下方法,浏览器会解释他为 Comment 类型:
<div id="myDiv"> <![CDATA[This is some content.]]> </div> console.log(document.getElementById("myDiv").firstChild); //Comment
createCDataSection()
方法 该方法用来创建 CDATA 区域,只需为其传入节点的内容即可
不常用。包含着与文档的 doctype 有关的所有信息。
该类型对象的三个属性:name、entities 和 notations。其中,name 表示文档类型的名称;entities 是由文档类型描述的实体的 NamedNodeMap 对象;notations 是由文档类型描述的符号的 NamedNodeMap 对象。一般来说只有 name 有点用。
console.log(document.doctype.name); //html
IE 不支持。
createDocumentFragment()
方法 主要作用就是用来避免通过逐个添加元素所导致的浏览器反复渲染新信息的问题,使用一个文档片段来保存创建的元素,然后再一次性将它们添加到文档中。如:
<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);
该对象又3个属性:name、value 和 specified。但使用 getAttribute()
、 setAttribute()
和 removeAttribute()
方法更好用。