一. 什么是DOM
DOM[文档对象模型](Document Object Module)定义了用户操作文档对象的接口,可以说DOM是自HTML将相关文档连接起来后伟大的创新,它使得用户对HTML有了空前的访问能力,并使得开发者能将HTML作为XML文档来处理.这讲我们主要介绍DOM模型的基础,包括页面中的节点,如何使用DOM.DOM与CSS等.
HTML的树形结构
通过这样的关系划分,整个HTML文档清晰可见,各个元素之间的关系很容易表达出来.
二. DOM模型中的节点
DOM中有3中节点分别是元素节点,文本节点,属性节点
元素节点:
可以说整个DOM模型都是由元素节点组成.包括<html>,<body>,<h1>,<p>,<li>
元素节点可以包含其它的元素,比如<li>就包含在<ul>中
文本节点:
在HTML中由标记搭建框架是不够的,页面最终是向用户展示内容
比如:<h2>中就有文本,这些文本就是所谓的文本节点.
属性节点:
就是标签元素中的属性
例如,所有的元素都有一个id属性、一个class属性等。因为属性总是被放在起始标签里,所以属性节点总是被包含在元素节点当中
三. 使用DOM
在了解DOM模型的框架和节点后,最重要的是使用这些节点来控制HTML网页,本节主要介绍如何利用DOM来操作页面文档,对于每一个DOM节点node,都有一系列的属性,方法可以使用,下面列举相关的属性和方法
Node的常用属性和方法
属性/方法
类型/返回类型
说明
nodeName
String
节点名称,根据节点的类型而定义
nodeValue
String
节点的值,同样根据节点的类型而定义
nodeType
Number
节点类型,常量值之一
firstChild
Node
指向childNodes列表中的第一个节点
lastChild
Node
指向childNodes列表中的最后一个节点
childNodes
NodeList
所有子节点的列表,方法item(i)可以访问第i+1个节点
parentNode
Node
指向节点父节点,如果已是根节点,返回null
1> 访问节点
DOM提供了一些便捷的方法来访问某些特定的方法来访问某些特定的节点.最基本的两种方法是
getElementById()和getElementsByTagNme()
getElementsByTagNme()用来返回一个包含某个相同标签名(也就是name相同)的元素的NodeList
var oLi document.getElementsByTagName("ll");
这里是返回文档中所有<li>元素列表,还需要特别注意的是,文档的DOM结构必须是在整个文档加载完毕以后才能正确分析出来.
同样可以取出某个节点下面的子节点
var oUl= document.getElementsByName("ul");
var oLi= oUl[1].getElementsByName("li");
alert(oLi.length+" "+oLi[0].tagName+" "+oLi[0].childNodes[0].nodeValue);
当然也可以直接查询name值
getElementById()返回id为指定值的元素.
注意:如果给定的id匹配某个元素的name属性,IE浏览器会返回这个元素,这是一个非常严重的bug,也是我们必须注意的,在搭建HTML框架时应当尽量避免id与其它元素的name属性重复.
案例做一个广告浮动
2> 检测节点类型
通过节点的nodeType属性可以检测出节点的类型,该属性返回一个代表节点类型的整数值,总共有12个可取值
例如:alert(document.nodeType)
真正有用的只有3种节点,就是我们前面提到3种节点
分别为:
(1) 元素节点nodeType值为1
(2) 属性节点nodeType值为2
(3) 文本节点nodeType值为3
这就意味着可以对某种类型的节点做单独处理.
3> 利用父子兄关系查找节点
父子兄关系是DOM模型中节点之间最重要的2种关系,前面一个例子我们就使用了节点的childNodes属性来访问元素几点所包含的文本几点.
父子关系
在获取某个节点之后,可以通过父子关系,利用hasChildNodes()方法和childNodes属性来获取该节点下面的所有子节点.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function myDom()
{
var myUl=document.getElementById("myList");
var myStr="";
if(myUl.hasChildNodes())
{
var myLi=myUl.childNodes;
for(i=0;i<myLi.length;i++)
{
myStr+=myLi[i].nodeName+"/n";
}
}
alert(myStr);
}
</script>
</head>
<body onload="myDom();">
<ul id="myList">
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li>板栗烧鸭</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
反过来利用节点找到所对应的父节点用parentNode属性
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Untitled Page</title>
<script language="javascript" type="text/javascript">
function myDom()
{
var myItem=document.getElementById("myfood");
alert(myItem.parentNode.tagName);
}
</script>
</head>
<body onload="myDom();">
<ul id="myList">
<li>糖醋排骨</li>
<li>圆笼粉蒸肉</li>
<li>泡菜鱼</li>
<li id="myfood">板栗烧鸭</li>
<li>麻婆豆腐</li>
</ul>
</body>
</html>
兄弟关系
在DOM中父子关系属于不同层次之间的关系,而在同一个层中常用到的便是兄弟关系.一般用到了这样的两个属性nextSibling和previousSibling
扩展:由于火狐等浏览器中会把包含很多空格作为文本的节点,因此以上代码只适合在IE浏览器中使用,在其它浏览器中要通过nodeType属性对节点类型进行判断
<script language="javascript" type="text/javascript">
function myDom()
{
var myItem=document.getElementById("myfood");
var item=myItem.previousSibling;
while(item.nodeType!=1 && item.previousSibling!=null)
{
item=item.previousSibling;
}
alert(item.tagName);
}
</script>
4> 设置节点属性
在找到需要的节点之后通常希望对其属性做相应的设置.DOM定义了两个便捷的方法来查询和设置节点的属性,即getAttribute()方法和setAttribute()方法
getAttribute()只有一个参数即要查询的属性名称,需要注意的地方是该方法不能通过document对象调用,只能通过一个元素节点来调用
Myimage.getAttribute(“title”)
setAttribute()设置一个属性
Myimage. setAttribute (“title”,”….”)
5> 创建和添加节点
createElement()创建元素节点
createTextNode()创建文本节点
appendChild()添加节点
Var op=document.createElement(“p”);
Var oText=document.createTextNode(“这是一段感人的故事”);
op.appendChild(oText);
document.body.appendChild(op);
6> 删除节点
removeChild() 通过父节点的removeChild()方法来完成,通常是找到要删除的节点.然后利用parentNode属性找到父节点,然后将其删除
Var op=doucument.getElementsByTagName(“p”)[0];
op.parentNode.removeChild(op);//找到父节点,然后删除自己
7> 替换节点
有时候不光是添加和删除,而是要替换页面中的某个元素.DOM提供了replaceChild()方法来完成这项任务.这个方法是针对要替换节点的父节点来操作的.
Var oldop=doucument.getElementsByTagName(“p”)[0];
Var op=document.createElement(“p”);
Var oText=document.createTextNode(“这是一段感人的故事”);
op.appendChild(oText);
oldop.parentNode.replaceChild(op,oldop);
8> 在特定节点前插入节点
insertBefore()在特定节点前插入节点.两个参数
Var oldop=doucument.getElementsByTagName(“p”)[0];
Var op=document.createElement(“p”);
Var oText=document.createTextNode(“这是一段感人的故事”);
op.appendChild(oText);
oldop.parentNode.insertBefore(op,oldop);
9> 在特定节点后插入节点
Var oldop=doucument.getElementsByTagName(“p”)[0];
Var op=document.createElement(“p”);
Var oText=document.createTextNode(“这是一段感人的故事”);
op.appendChild(oText);
oldop.parentNode.insertAfter(op,oldop);
10> 使用非标准DOM的innerHTML属性
四. DOM与CSS
1> 三位一体的网页
我们在浏览器里看到的网页其实是由以下三层信息构成的一个共同体:
结构层
表示层
行为层
1. 结构层
网页的结构层由HTML或XHTML之类的标记语言负责创建。标签(tag),也就是那些出现在尖括号里的单词,对网页内容的语义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。
2. 表示层
网页的表示层由CSS负责创建。
3. 行为层
网页的行为层负责回答“内容应该如何对事件做出反应”这一问题。这是Javascript和DOM主宰的领域。
注意:网页的表示层和行为层总是存在的,即使我们未明确地给出任何具体地指令也是如此。此时,浏览器将把它的默认样式和默认事件处理函数施加在网页的结构层上。
4. 分离
这意味着:
使用(X)HTML去搭建文档的结构。
使用CSS去设置文档的呈现效果。
使用DOM脚本去实现文档的行为。
注意:在这三种技术之间存在着一些潜在的重叠区域。
2>使用 style属性
3>使用className属性