DOM操作
DOM是Document Object Model的缩写,即文档对象模型,是基于文档编程的一套API接口,1998年W3C发布了一级的DOM规范,这个规范允许访问和操作HTML页面中的每个单独元素,如网页的表格,图片。文本,表单元素等。
使用JavaScript操作DOM时分为三个方面:DOM Core(核心),HTML-DOM和CSS-DOM。通过这些标准,开发人员可以让网页真正的动起来,动态地添加,修改,删除数据,使用户和计算机的交互更加便捷,交互也更加丰富。
1.DOM Core
DOM Core不是JavaScript的专属品,任何一种支持DOM编程的语言都可以使用它,它的用途不仅限去处理一种使用标记语言编写出来的文档HTML。
2.HTML-DOM
使用JavaScript和DOM为HTML文档编写脚本时,有许多专属的HTML-DOM的属性,HTML-DOM比DOM Core出现的更早,它提供了一些更简单的标记来描述各种HTML元素的属性,如document.forms,获取表单对象。
需要提醒的是,获取DOM模型中的某些对象,属性,既可以使用DOM Core实现,也可以使用HTML-DOM实现,相对于DOM Core获取对象,属性而言,当使用HTML-DOM时,代码通常更为简短,只是它的应用范围没有DOM-Core广泛,仅适于处理HTML文档。
3.CSS-DOM
CSS=DOM是针对CSS的操作,在javascript中,CSS-DOM技术主要作用是获取和设置style对象的各种属性,即CSS属性,通过改变style对象的各种属性,可以使用网页呈现出各种不同的效果,如element.style.color=“red”;,设置文本为红色。
节点和节点关系
DOM是以树状结构组织的HTML文档,根据DOM概念,我们可以知道,HTML文档中每个标签或元素都是一个节点,在DOM中是这样规定的。
- 整个文档是一个文档节点。
- 每个HTML标签是一个元素节点。
- 包含在HTML元素中的文本是一个文本节点。
- 每个HTML属性是一个属性节点。
- 注释属于注释节点
<html>
<head lang="en">
<meta charset="UTF-8">
<title>DOM节点</title>
</head>
<body>
<img src="img/book.jpg" alt="水果" id="fruit"/>
<h1>喜欢的水果</h1>
<p>DOM应用</p>
<script>
alert("123")
</script>
</body>
</html>
这个示例的文档由html,head,title,body,img,h1,p及文本节点组成,这些节点都存在这层次关系,他们的关系如下图显示
使用父(parent),子(child),和兄弟(sibling)等术语来描述这些节点的层次关系,父节拥有子节点,同级的子节点被称为兄弟节点他们的关系如下:
- 在节点树中,顶部节点被称为根节点如html节点。
- 每个节点都有父节点,除了根节点没有父节点,如head和body的父节点都是html,文本节点“DOM应用”的父节点就是p节点。
- 一个节点可以拥有任何数量的子节点,如body节点的子节点有img,h1和p。
- 兄弟节点是拥有相同父节点的节点,如img,h1和p就是兄弟节点,它们的父节点均为body节点。
HTML文档中标签,元素等都是一个节点,并且各个节点之间都存在着关系,因此javascript可以通过访问或改变节点的方式来改变页面的内容,使用javascript操作节点主要是访问节点,在文档中创建和增加节点,删除节点,替换节点,以及操作节点属性和样式等,
访问节点
使用DOM Core访问HTML文档的节点主要有两种方式,一种是使用getElement系列方法访问指定节点,另外一种是根据节点的层次关系访问节点。
1.使用getElement系列方法枉访问指定节点
- getElementById:返回按id属性查找的第一个对象的引用。
- getElementsByName():返回带有指定名称name查找的对象的集合,由于一个文档中可能会有多个同名节点如(复选款,单选按钮)因此返回的是元素数组。
- getElementsTagName():返回带有指定标签名TagName查找的对象的集合,由于一个文档中可能会有多个同类型的标签节点(如图片组,文本输入框)因此返回元素数组。
2.根据层次关系访问节点
通过getElementById(),getElementsByName(),getElementsTagName()这三种方法可查看HTML文档中的任何元素,但是这三种方法都会忽略文档的结构,因此在HTML DOM中提供了如下表所示的一些节点属性,这些属性可遵循文档的结构,在文档的局部进行“短距离的查找元素”
注意:在IE下支持firstChild,lastChild,previousSibling,nextSibling,但是在FireFox下由于它会把标签之间的空格,换行等当成文本节点,因此为了准确的找到相应的元素,使用firstElementChild,lastElementChild,previousElementSibling,nextElementSibling来兼容浏览器。
需要获取不同的节点时,使用节点属性和element属性的写法如下图所示:
节点信息
节点是DOM层次结构中的任何类型的对象的通用名称,每个节点都拥有包含着关于节点某些信息属性,这些属性如下:
- nodeName(节点名称)
- nodeValue(节点值)
- nodeType(节点类型)
nodeName属性包含某个节点的名称,元素节点的nodeName是标签名称,属性节点的nodeName是属性名称,文本节点的nodeName永远是#text,文档节点的nodeName永远是#document
nodeValue节点值,对于文本节点,nodeValue属性包含文本,对于属性节点,nodeValue属性包含属性值;nodeValue属性对于文档节点和元素节点都是不可用的。
nodeType属性可返回节点的类型,是一个只读属性,如返回的是元素节点,文本节点等。
示例:
<ul id="nodeList"><li>nodeName</li><li>nodeValue</li><li>nodeType</li></ul><p></p>
<script>
var nodes = document.getElementById("nodeList");
var type1 = nodes.firstChild.nodeType;
var type2=nodes.firstChild.firstChild.nodeType;
var name1=nodes.firstChild.firstChild.nodeName;
var str=nodes.firstChild.firstChild.nodeValue;
var con="type1:"+type1+"<br/>type2:"+type2+"<br/>name1:"+name1+"<br/>str:"+str;
document.getElementById("nodeList").nextSibling.innerHTML=con;
</script>
结果如下所示:
操作节点的属性
HTML DOM提供了获取及改变节点属性值的标准方法
- getAttribute(“属性名”) :用来获取属性的值
- setAttribute(“属性名”,“属性值”):用来设置属性的值。
示例:
<body>
<p>选择你喜欢的书:<input type="radio" name="book" onclick=" book()">我和狗狗一起活下来 <input type="radio" name="book" onclick=" book()">灰霾来了怎么办</p>
<div><img src="" alt="" id="image" onclick="img()"><span></span></div>
<script>
function book(){
var ele=document.getElementsByName("book");
var img = document.getElementById("image");
if(ele[0].checked){
img.setAttribute("src","images/dog.jpg");
img.setAttribute("alt","我和狗狗一起活下来");
img.nextSibling.innerHTML="我和狗狗一起活下来";
}else if(ele[1].checked){
img.setAttribute("src","images/mai.jpg");
img.setAttribute("alt","灰霾来了怎么办");
img.nextSibling.innerHTML="灰霾来了怎么办";
}
}
function img(){
var alt = document.getElementById("image").getAttribute("alt");
alert("图片的alt:"+alt);
}
</script>
</body>
注意:当使用getAttribute()方法读取属性值时,如果属性不存在,则getAttribute()的返回值为null。
创建和插入节点
使用javascript操作DOM有很多方法可以创建或增加一个新节点,主要方法如下标所示:
注意:
- insertBedore(A,B)中有两个参数。A是必填项,表示新插入的节点;B是可选项,表示新节点被插到B节点的前面。
- clonenode(deep)中的参数deep为布尔值,若deep值为ture,则复制该节点即该节点的所有子节点,如deep的值为false,则只复制该节点和其属性。
示例:
<body>
<p>选择你喜欢的书:<input type="radio" name="book" onclick="book()">我和狗狗一起活下来<input type="radio" name="book" onclick="book()">灰霾来了怎么办</p>
<div></div>
<script>
function book(){
var ele = document.getElementsByName("book");
var bname = document.getElementsByTagName("div")[0];
if(ele[0].checked){
var img = document.createElement("img");
img.setAttribute("src","images/dog.jpg");
img.setAttribute("alt","我和狗狗一起活下来");
bname.appendChild(img);
}else if(ele[1].checked){
var img = document.createElement("img");
img.setAttribute("src","images/mai.jpg");
img.setAttribute("alt","灰霾来了怎么办");
img.setAttribute("onclick","copyNode()");
bname.appendChild(img);
}
}
function copyNode(){
var bname=document.getElementsByTagName("div")[0];
var copy=bname.lastChild.cloneNode(false);
bname.insertBefore(copy,bname.firstChild);
}
</script>
</body>
删除和替换节点
使用HTML Core删除或替换节点的方法如表所示:
方法replaceChild(newNode,oldNode)中的两个参数,newNode是替换的新节点,oldNode是要被替换的节点。
示例:`
<body>
<ul>
<li>
<img src="images/f01.jpg" id="first">
<p><input type="button" value="删除我吧" onclick="del()"></p>
</li>
<li>
<img src="images/f02.jpg" id="second">
<p><input type="button" value="换换我吧" onclick="rep()"></p>
</li>
</ul>
<script>
function del(){
var delnode = document.getElementById("first");
delnode.parentNode.removeChild(delnode);
}
function rep(){
var oldnode = document.getElementById("second");
var newnod = document.createElement("img");
newnod.setAttribute("src","images/f03.jpg");
oldnode.parentNode.replaceChild(newnod,oldnode);
}
</script>
</body>
从代码中可以看出 点击“删除我把”按钮,调用del()函数首先访问第一个图片,然后使用parentNode获取当前图片的父级,使用removeChild()删除当前图片
操作节点样式
在javaScript中,有两种方式可以动态改变的改变样式的属性,一种是使用样式的style属性,另一种是使用样式的className属性,下面介绍
1.style属性
在HTML DOM中,style是一个对象,代表一个单独的样式声明,可通过应用样式的文档或元素访问style对象,语法
HTML元素。style.样式属性=“值”;
在页面中有一个id为tites的div,要改变div中的字体颜色为红色,字体大小为13px代码如下所示:
document.getElementById("tites").style.color="red";
document.getElementById("tites").style.fontSize="13px";
在javascript中使用CSS样式与在HTML中使用CSS稍有不同,在javascript中“-”表示减号,如果样式属性中带有“-”号。则要省去减号,并且“-”号后的首字母要大写。
使用这些样式可以动态的改变背景,字体的大小,颜色等。例如,浏览网站时经常遇到的菜单特效,当鼠标指针移到菜单上时,菜单的背景,字体颜色,样式,大小等发生变化。
鼠标对应的常用事件
名称 | 描述 |
---|---|
onclick | 当用户单击某个对象时调用事件 |
onmouseover | 鼠标移到某个元素上 |
onmouseout | 鼠标从某个元素移开 |
onmousedown | 鼠标按钮被按下 |
示例:
<section id="shopping">
<div id="cart" onmouseover="over()" onmouseout="out()">我的购物车<span>1</span></div>
<div id="cartList">
<h2>最新加入的商品</h2>
<ul>
<li><img src="images/makeup.jpg"></li>
<li>倩碧经典三部曲套装(液体皂200ml+明肌2号水200ml+润肤乳125ml)</li>
<li>¥558.00×1<br/>删除</li>
</ul>
<div class="footer">共1件商品<span>共计¥558.00</span> <span>去购物车</span></div>
</div>
</section>
<script>
//初始状态下,cartList层被隐藏
document.getElementById("cartList").style.display="none";
function over(){
document.getElementById("cart").style.backgroundColor="#ffffff";
document.getElementById("cart").style.zIndex="100";
document.getElementById("cart").style.borderBottom="none";
document.getElementById("cartList").style.display="block";
document.getElementById("cartList").style.position="relative";
document.getElementById("cartList").style.top="-1px";
}
function out(){
document.getElementById("cart").style.backgroundColor="#f9f9f9";
document.getElementById("cart").style.borderBottom="solid 1px #dcdcdc";
document.getElementById("cartList").style.display="none";
}
</script>
2.className属性
在HTML DOM中,className属性可设置或返回元素的class样式,语法如下
HTML元素.className="样式名称";
获取元素的样式
在javascript中可以使用style属性获取样式的属性值语法
HTML元素.sytle.样式属性;
在javascript中,使用style获取元素属性的方式只能获取内联样式的属性值,无法获取内部样式表或外部样式表中的属性值,但是在实际工作中通常是样式和内容相分离的,所有实际工作中并不用 “html元素.sytle。样式属性”这种方式获取样式的属性值。
微软为每个元素提供了一个currentStyle对象,它包含了所有元素的style对象的特性和任何未被覆盖的CSS规则的style特性,语法
html元素.currentStyle.样式属性;
currentstyle对象的特性是只读的,如果要给样式属性赋值,则必须使用前面学过的style对象。
虽然使用currentStyle可以获取样式属性的值,但是它只局限于IE浏览器,其他浏览器却无法获得样式的属性值,不过DOM提供了一个getComputedStyle()方法,这个方法接受两个参数,需要获取样式的属性值,语法如下:
document.defaultView.getComputedStyle(元素,null).属性;
注意:
- 虽然getComputedStyle()方法是DOM提供的,但是IE游览器却不支持,而Firefox,opera,safari,chrome浏览器是支持的。
- 在IE浏览器下还是需要使用currentStyle来获取样式的属性值。