HTML DOM------(转)
什么是DOM?
通过 JavaScript,您可以重构整个HTML文档。您可以添加、移除、改变或重排页面上的项目。要改变页面的某个东西,JavaScript就需要对HTML文档中所有元素进行访问的入口。这个入口,连同对HTML 元素进行添加、移动、改变或移除的方法和属性,都是通过文档对象模型来获得的(DOM)。在 1998 年,W3C 发布了第一级的 DOM 规范。这个规范允许访问和操作 HTML 页面中的每一个单独的元素。所有的浏览器都执行了这个标准,因此,DOM 的兼容性问题也几乎难觅踪影了。DOM 可被 JavaScript 用来读取、改变 HTML、XHTML 以及 XML 文档。
DOM 是一种接口,使用该接口可以轻松访问页面中所有标准组件(轻松获取和操作网页中的数据,脚本和表现层对象),重要的是解决了Netscape的javascript和Microsoft的Jscript之间的冲突,给web开发者一套标准的方法。
注:DOM不属于某一语言,也不仅仅面对javascript,它仅仅定义一个标准的接口。
DOM分为三个方向,DOM Core(核心),HTML-DOM和CSS-DOM.
1 DOM Core
javascript中有getElementById(),getElementByTagName(),getAttribute(),setAttribute等方法。
例:
获取表单对象:document.getElementByTagName('form');
获取某元素的src属性: element.getAttribute('src');
2 HTML-DOM
提供了简明的记号描述各宗HTML元素属性
例:
window.location获取一个location对象
window.alert()弹出一个警告窗口
document.write()在html文档上写相关内容
获取表单对象:document.froms
获取某元素src属性:element.src
3 CSS-DOM
在javascript中,CSS-DOM主要用来获取和设置style对象的各种属性.
设置某元素style对象字体颜色 element.style.color = "red";
节点:根据 DOM,HTML 文档中的每个成分都是一个节点。 DOM 是这样规定的:
- 整个文档是一个文档节点
- 每个 HTML 标签是一个元素节点
- 包含在 HTML 元素中的文本是文本节点
- 每一个 HTML 属性是一个属性节点
- 注释属于注释节点
Node 层次 节点彼此都有等级关系。HTML 文档中的所有节点组成了一个文档树(或节点树)。HTML 文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止。
下面这个图片表示一个文档树(节点树):
文档树(节点数) 请看下面这个HTML文档:
<html>
<head>
<title>DOM Tutorial</title>
</head>
<body>
<h1>DOM Lesson one</h1>
<p>Hello world!</p>
</body>
</html>
上面所有的节点彼此间都存在关系。除文档节点之外的每个节点都有父节点。举例,<head> 和 <body> 的父节点是 <html> 节点,文本节点 "Hello world!" 的父节点是 <p> 节点。大部分元素节点都有子节点。比方说,<head> 节点有一个子节点:<title> 节点。<title> 节点也有一个子节点:文本节点 "DOM Tutorial"。当节点分享同一个父节点时,它们就是同辈(同级节点)。比方说,<h1> 和 <p>是同辈,因为它们的父节点均是 <body> 节点。节点也可以拥有后代,后代指某个节点的所有子节点,或者这些子节点的子节点,以此类推。比方说,所有的文本节点都是 <html>节点的后代,而第一个文本节点是 <head> 节点的后代。节点也可以拥有先辈。先辈是某个节点的父节点,或者父节点的父节点,以此类推。比方说,所有的文本节点都可把 <html> 节点作为先辈节点。
获取(R)
1. getElementById(id)、getElementsByName(name)、getElementsByTagName(tagName),这三种方法都会忽略文档的结构。
- getElementById(id):通过id获取元素节点,如果页面上含有多个相同id的节点,那么只获取第一个节点,理论上,id在页面中应该是唯一的。jquery中通过$("#id")来获得节点,这种方式类似于css中的id选择器。
- getElementsByName(name):通过name获取一组元素节点,返回的是具有相同name的节点数组。注意,这个方法在IE和W3C(FireFox、Chrome)下表现是不一样的,这个方法应该不是DOM LEVEL 1里的规范,IE支持LEVEL 1,和后来的标准就有很多差异了。主要有如下几点区别:getElementsByTagName(tagName):通过tagName获取一组元素节点,返回的是具有相同tagName的节点数组。这个方法的特殊之处在于不仅仅可以通过顶层document来使用,所有元素节点都可以使用。如:document.getElementById("container").getElementByTagName("div");,这跟css样式有些相像,比如定义id为container元素节点下的所有div样式:.container div{display:none;}。
- IE下通过getElementsByName(name)只能取得表单元素的节点;
- IE下不区分id和name,也就是说通过getElementsByName(name)取得的节点数组也包含id和name相同的了,通过getElementById(id),也可以将name作为参数,看MSDN的官方说明。
-
<html> <head> <title>节点的增删改查</title> <script type="text/javascript"> function init() { alert(document.getElementById("div1").nodeName); alert(document.getElementsByName("container").length);// IE结果是2,Chrome、FF结果是3 alert(document.getElementById("container").value);// IE结果是1,Chrome、FF结果是2 } </script> </head> <body onload="init()"> <div id="div1" name="container">1</div> <!--<div id="div1"></div>--> <span id="div1" name="container">2</span> <input name="container" type="text" value="1" /> <input id="container" type="text" value="2" /> </body> </html>
2. parentNode、firstChild以及lastChild,这三种属性都可以递归来使用。
html实例:
-
<html> <head> <title>节点的增删改查</title> </head> <body> <div id="level1"> <div id="level21"> <div id="level3"><div> </div> <div id="level22"></div> </div> </body> </html>
- parentNode:取得当前节点的父节点,如document.getElementById("level21").parentNode,也可以obj.parentNode.parentNode.parentNode。
- firstChild:取得当前节点的第一个子节点,如document.getElementById("level1").firstChild;,也可以document.getElementById("level1").firstChild.firstChild。
- lastChild:取得当前节点的最后一个子节点,如document.getElementById("level1").lastChild。
3. 根节点,document.documentElement得到HTML以及XML文档中的根节点,document.body提供了对body节点的直接访问。
4. 所有子节点:childNodes和children,各种版本各种浏览器下表现都不一样。
5. 节点信息:nodeName(tagName)、nodeValue、nodeType.
- nodeName
- 元素节点的nodeName是标签名称
- 属性节点的nodeName是属性名称
- 文本节点的nodeName是#text
- 文档节点的nodeName是#document
- nodeValue
- 文本节点的nodeValue包含文本
- 属性节点的nodeValue包含属性值
- 元素节点和文档节点没有nodeValue
- nodeType
-
元素类型 节点类型 元素 1 属性 2 文本 3 注释 8 文档 9
创建(C)&修改(U)&删除(D)
写一个点击单元格变为文本框的示例。
<html>
<head>
<title>节点的增删改查</title>
<script type="text/javascript">
function appendInput(tdNode) {
// 创建input元素节点,createElement创建元素节点,createTextNode(value)创建文本节点
var inputNode = document.createElement("input");
// 给input属性赋值
inputNode.value = tdNode.innerText;
inputNode.name = "value";
// 删除单元格的文本节点,参数为要删除的子节点对象
tdNode.removeChild(tdNode.firstChild);
// 将input追加到单元格中,appendChild(node)将node追加到父节点末尾,insertBefore(node1, node2)是将node1加入到node2之前
tdNode.appendChild(inputNode);
// 聚焦input,在chrome下,光标直接定位到文本最右边,IE下确实最左边
inputNode.focus();
// 将光标移到文本最右边
moveCursorToRight(inputNode);
}
/** 光标移到文本最右边 */
function moveCursorToRight(obj) {
var r = obj.createTextRange();
r.moveStart('character', obj.value.length);
r.collapse(true);
r.select();
}
</script>
</head>
<body>
<table>
<tr>
<td onclick="appendInput(this)">Hello!</td>
</tr>
</table>
</body>
</html>