DOM是针对HTML和XML文档的一个API。DOM描写了一个条理化的节点树,许可开发人员增加、移除和修正页面的某一部份。
节点条理
<!DOCTYPE html>
<html>
<head>
<title>sample page</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
文档节点(Document node)是每一个文档的根节点(在浏览器中对应的是document),在这个例子中,文档节点有两个子节点,一个是<!DOCTYPE html>
(DocumentTyep范例),另一个是<html>
(Element范例)。文档元素是文档最外层的元素,文档中的其他一切元素都是包括在文档元素中。每一个文档只能有一个文档元素,在HTML页面中,文档元素一直是<html>
元素。
Node范例
JavaScript中,一切节点范例都继续自Node范例,因而一切节点范例都同享着雷同的基础属性和要领
每一个节点都有一个nodeType属性,用于表明节点的范例.
肯定节点范例
if (someNode.nodeType == Node.Element_NODE){
alert("Node is an element"); // 表明该节点是一个HTML元素
}
或许
if (someNode.nodeType == 1){
alert("Node is an element"); // 表明该节点是一个HTML元素
}
nodeName和nodeValue
假如node是HTML标签,则nodeName的值就是元素的标署名,关于非文档节点,返回null
if (someNode.nodeType == 1){
tagName = someNode.nodeName;
}
关于文档节点(HTML标签)来讲, nodeValue返回null. 关于text, comment, 和 CDATA 节点来讲, nodeValue返回该节点的文本内容. 关于 attribute 节点来讲, 返回该属性的属性值.
节点之间的关联(node的一些属性):
node.childNodes
node.parentNode
node.previousSibling
node.nextSibling
node.firstChild
node.lastChild
操纵节点(node的一些要领)
node.appendChild():返回新增的节点,这个返回的节点是存在于DOM树中的节点,能够经由历程上面的属性接见DOM树中的其他节点
var returnNode = parentNode.appendChild(newNode);
insertBefore(newNode, baseNode): 同样会返回一个新节点,同上
replaceChild(newNode, replacedNode): 同样会返回一个新节点,同上
removeChild(node):会返回一个节点,该节点不存在于DOM树中
cloneNode:
// 实行深复制,即复制节点及其全部子树
var returnNode = someNode.cloneNode(true);
// 实行浅复制,只复制节点自身
var returnNode = someNode.cloneNode(false);
Document范例
JavaScript经由历程Document范例示意文档。在浏览器中,document对象是HTMLDocument(继续自Document范例)的一个实例,示意全部HTML页面。document对象是window对象的一个属性,因而能够作为全局对象来接见
文档子节点
Document节点(浏览器中是document)的子节点多是DocumentType(最多一个,比方<!DOCTYPE html>
)、Element(最多一个比方 <html>
)、ProcessingInstruction、Comment
document.documentElement 一直指向HTML页面中的文档元素(
<html>
)document.body直接返回对<body>元素的援用
document.doctype会返回对
<! DOCTYPE HTML>
的援用document.title返回文档题目的内容(只读)
document.childNodes会返回[
<! DOCTYPE HTML>
,html
] (假如存在DOCTYPE的话)
文档信息:(能够猎取或许设置这些属性)
document.title
document.URL: 包括页面完全的URL(地址栏中的URL)
document.domain:
document.referrer: 链接到当前页面的谁人页面的URL
查找元素
document.getElementById()
document.getElementsByTagName():返回HTMLCollection对象
document.getElementsByName():返回带有给定name特征的一切元素,返回HTMLCollection对象
文档写入:
document.write():原样写入传入的字符串
document.writeln(): 在字符串的末端增加一个换行符
...
<body>
<p>the current date and time is:
<script>
document.write("<strong>" + (new Date().toString() + "</strong>");
</script>
</body.
在 页面显现历程 中,经由历程上面的体式格局能够在指定位置输出内容
这两个要领假如在页面加载完毕后被挪用,那末输出内容会重写全部页面
Element范例
要接见元素的标署名,能够运用nodeName属性或许tagName属性,这两个属性会返回雷同的值。注意在HTML中tagName会返回大写的标署名,在XML中返回值和代码中的标签一致。
<div id="myDiv"></div>
var div = document.getElementById("myDiv");
alert(div.tagName); // DIV
alert(div.tagName == div.nodeName); //true
alert(div.tagName.toLowerCase() == "div"); // true
HTML元素
能够直接接见和修正的属性:
id:
element.id
title:
element.title
className:
element.className
lang
dir: 笔墨方向
<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>
var div = document.getElementById("myDiv");
alert(div.id);
alert(div.className);
alert(div.title);
alert(div.lang);
alert(div.dir);
获得特征: getAttribute
<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>
var div = document.getElementById("myDiv");
alert(div.getAttribute("id"));
alert(div.getAttribute("class");
alert(div.getAttribute("title");
alert(div.getAttribute("lang");
alert(div.getAttribute("dir");
关于style、onclick这类特别的特征,getAttribute()只能返回响应代码的字符串,因而在经由历程JavaScript以编程的体式格局操纵DOM时,开发人员常常不运用getAttribute(),而是只运用对象的属性(div.id)
任何元素的一切特征,也都能够经由历程DOM元素自身的属性来接见。不过只要公认的特征才会以属性的情势增加到DOM对象中。 以下面的元素为例:
<div id="myDiv" align="left" my_special_attribute="hello!"></div>
由于id和align在html中是<div>的公认特征,因而在该元素的DOM对象中也将存在对应的属性。
alert(div.id); // "myDiv"
alert(div.my_special_attribute); // undefined
alert(div.align); //"left"
设置特征–setAttribute()
setAttribute()接收两个参数,要设置的特征名和值。假如特征已存在,则会替代已有的值,假如特征不存在,则会建立该属性并设置响应的值。
<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>
var div=document.getElementById("myDiv");
div.setAttribute("id","someOtherId");
移除属性–removeAttribute()
<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>
var div=document.getElementById("myDiv");
div.removeAttribute("id");
attributes属性:运用不轻易不常常运用,然则能够用来遍历元素特征
Element范例是运用attribute属性的唯一一个DOM节点范例。attribute属性中包括一个NamedNodeMap。元素的每一个特征都有一个Attr节点示意,每一个节点都保留在NamedNodeMap对象中。NamedNodeMap对象具有以下要领。
getNamedItem(name):返回nodeName属性即是name的节点
removeNamedItem(name): 移除nodeName属性即是name的节点
setNamedItem(node): 向列表中增加节点,以节点的nodeName属性为索引
item(pos): 返回位于数字pos位置处的节点
var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;
运用不轻易不常常运用,然则能够用来遍历元素特征
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;
pairs.push(attrName + " =\"" + attrValue + "\"");
. }
return pairs.join(' ');
}
建立元素
document.createElement()要领能够建立新元素,这个要领只接收一个参数,即要建立元素的标署名
var div = document.createElement("div");
div.id = "myDiv";
div.className = "box";
// 此时新元素还没有增加到文档树中,因而设置这些特征不会影响浏览器的显现
// 把新元素增加到文档树中:appendChild()、insertBefore()、replaceChild()
document.body.appendChild(div);
元素的子节点
假如想经由历程某个特定的标署名获得子节点或许子女节点,能够在元素上挪用getElementsByTagName()要领
Text范例
文本节点由Text范例示意,包括的是能够根据字面诠释的纯文本内容,然则不能包括HTML代码
主要的特性:
nodeType的值为3
nodeName为#text
nodeValue的值为节点包括的文本
parentNode是一个Element
没有(不支持)子节点
有一些操纵节点中文本的要领:
appendData(text): 将text增加到末端
deleteData(offset, count): 从offset指定的位置最先,删除count个字符
insertData(offset, text):
replaceData(offset, count, text)
splitText(offset): 从offset指定位置将当前文本节点分红两个 文本节点
…
假如在一个包括两个或多个文本节点的父元素上挪用normalize()要领,则会将一切文本节点兼并成一个节点,效果节点的nodeValue即是将兼并前每一个文本节点的nodeValue值拼接起来的值。
DocumentFragment范例:
在一切的节点范例中,只要DocumentFragment在文档中没有对应的标记。DOM划定文档片断是一种“轻量级”的文档,能够包括和掌握节点,但不会像完全的文档那样占用分外的资本。
虽然不能把文档片断直接增加到文档中,然则能够将它作为一个堆栈来运用,即在内里保留未来可能会增加到文档中的节点。
建立文档片断的体式格局:document.createDocumentFragment()
var fragment = document.createDocumentFragment();
var ul = document.getElementById('myList');
var li = null;
//位ul增加三个li
for(var i=0; i<3; i++){
li = document.createElement("li");
li.innetText = "Item" + (i+1);
fragment.appendChild(li);
}
ul.appendChild(fragment);
上面的例子是为ul元素增加3个列表项,假如逐一地增加列表项,将会致使浏览器频仍衬着新信息。为防止这个题目,能够运用frament,将一切列表项先增加到fragment中,末了将fragment增加到文档中。经由历程这类体式格局削减了浏览器的衬着次数。
DOM操纵手艺
动态剧本
插进去外部文件
function loadScript(url){
var script = document.createElement('script');
script.type = "text/javascript";
script.src = url;
document.body.appendChild(script);
}
行内体式格局
var script = document.createElement('script');
script.type = "text/javascript";
script.appendChild(document.creatTextNode('function sayHi(){alert('hi');}'));
document.body.appendChild(script);
动态款式
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);
}
操纵表格
HTML DOM为<table>
, <tbody>
, <tr>
元素增加了一些属性和要领,经由历程这些属性和要领,我们能够轻易的对表格举行操纵
运用NodeList
NodeList,NamedNodeMap和HTMLCollection都是动态的,每当文档构造发生变化时,它们都邑获得更新。
一般来讲,应当只管削减接见NodeList的次数,由于每次接见NodeList,都邑运转一次基于文档的查询,所以能够斟酌将从NodeList中掏出的值缓存起来。
总结
DOM操纵往往是JavaScript顺序中开支最大的部份,而因接见NodeList致使的题目为最多。NodeList对象都是“动态的”,这就意味着每次接见NodeList对象,都邑运转一次查询。有鉴于此,最好的方法就是只管削减DOM操纵。