一篇文章搞懂DOM
Posted Thinkguo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文章搞懂DOM相关的知识,希望对你有一定的参考价值。
学习javascript肯定是会遇到DOM操作,那么什么是DOM?它又是干嘛用的?这篇文章为你揭晓答案。
DOM是document object model的缩写,简称文档对象模型。
简单的说DOM是一套对文档的内容进行抽象和概念化的方法。我们可以把html文档模型化,当作对象来处理。
基本概念:
文档(document): HTML或XML文件。
节点(node):HTML文档中的所有内容都可以称之为节点,常见的节点有 元素节点 属性节点 文本节点 注释节点。
元素(element): HTML文档中的标签可以称为元素。
我们可以把一个HTML文档看做一个树形结构的对象,每一个标签会形成一个分支,这样就很容易理解了,如下图所示(图片来自w3school)。
知道了什么是DOM,肯定要问DOM有什么用?
DOM把HTML文档抽象成一个对象,肯定是为了方便使用JavaScript对HTML文档进行操作。DOM的作用就是为了对页面的结构内容进行操作,增加页面的动态特性。
好了,知道了DOM是干嘛用的,那么下面我们就学习如何进行DOM操作。
DOM操作主要分四个部分:
1、获取HTML节点及修改节点的属性
2、修改节点的样式
3、给节点绑定事件
4、节点操作
现在我们进行一一介绍
获取HTML节点与修改节点属性(包含表单元素)
DOM提供了三个获取节点的方法
方法一:
getElementById() //根据id属性获取一个DOM对象,区分大小写,符合代码规范
通过id寻找一个元素(找到的是一个元素对象) 该方法只能被document对象调用(同一个文档中id不能重复)。
<div id="box"></div>
var box = document.getElementById(“box”);
方法二:
getElementsByTagName() //根据标签返回多个DOM对象
通过标签名寻找一类元素(找到的是由元素对象组成的伪数组) 即可以被document调用,又可以被元素对象调用,被元素对象调用时表示在该元素对象内部执行查找。
通常针对多个标签,而且常会要用到for循环。
<div class="cl" id=“cl”> <div class="cl2"></div> <div class="cl2"></div> </div> <div class="cl"></div> <div class="cl"></div> var divs = document.getElementsByTagName("div");// 获取页面上所有div,divs是一个伪数组 var cl = document.getElementById("cl");// 获取id为cl的元素 var cl2s = cl.getElementsByTagName("div");// 获取cl元素下面所有的div标签,cl2s是一个伪数组
方法三:
getElementsByClassName()
通过类名寻找一类元素。
<div class="cl" id=“cl”> <p class="cl"></div> <span class="cl"></div> </div> <a class="cl"></a> var cls = document.getElementsByClassName("cl");//获取到的是一个伪数组,里面装的是div p span a这四个元素对象
获得到了节点元素后我们就可以对节点元素的属性进行修改了。
DOM也提供了两个方法供我们获取和修改元素的属性值。
getAttribute()
getAttribute是一个函数,用于获取节点属性。它只有一个参数,即所需要查询的属性的名字。getAttribute不属于document对象,所有不能通过document对象调用,只能通过元素节点对象调用。
<div id="box" title=hello></div>
var box = document.getElementById(“box”); console.log(box.getAttribute(“title”));
通过这个方法我们可以获取元素box的title属性值为hello。
setAttribute()
setAttribute也是一个函数,用于修改节点属性。与getAttribute用法类似,不同的地方在于它有两个参数,第一个为属性名,第二个参数为设定的属性值。
<div id="box" title=hello></div> var box = document.getElementById(“box”); console.log(box.setAttribute(“title”,”world”));
此时,box节点的title属性值已经变为world。
是不是感觉so easy.
其实还有更为简便的方法来修改属性值,直接使用点语法就可以了。
获取属性值
var 变量=box.title;
修改属性值
box.属性名 = “属性值”;
是不是感觉更简单呢。
在此我只举例了title属性,当然元素的属性还有很多,比如img标签的src属性,我们可以更改src属性来切换图片。还可以设置表单元素的属性
type可以设置input元素的类型;
value可以设置input元素的值;
checked可以设置input元素是否选中;
selected 可以设置下拉列表select中的option是否被选中;
disabled 可以设置input元素是否被禁用。
好了,属性的操作就到此为止。
获取节点与控制样式
关于节点的获取,上面只用到了三个方法,但是实际的项目HTML文档往往是很复杂的,
文档中所有的节点之间都存在这样或那样的关系。节点间的各种关系可以用传统的家族关系来描述,相当于把文档树比喻成家谱。在 HTML 中,可以将<body>元素看成是<html>元素的子元素;相应地,也就可以将<html>元素看成是<body>元素的父元素。而<head>元素,则可以看成是<body>元素的同胞元素,因为它们都是同一个父元素<html>的直接子元素。
首先我们来认识一下文档的层级结构,都有那些关系。
childNodes //子节点
children //子元素 虽然不是早期DOM标准中的方法,但是所有浏览器都支持
nextSibling //下一个兄弟节点
nextElementSibling //下一个兄弟元素 有兼容性问题
previousSibling//上一个兄弟节点
previousElementSibling //上一个兄弟元素 有兼容性问题
firstChild //第一个节点
firstElementChild //第一个子元素 有兼容性问题
lastChild //最后一个子节点
lastElementChild //最后一个子元素 有兼容性问题
parentNode //父节点 (一定是元素节点,所以无需处理)
所有获取节点相关属性都没有兼容性问题
注意:节点和元素不是同一个概念,文章开头说过,在此提醒一下。
获取子节点&子元素
- childNodes: 获取指定元素的子节点,包括文本节点、元素节点等
- children: 获取知道元素的子元素,只会获取元素节点。<ul id="list">
<li><a href="javascript:void(0)">首页</a></li> <li><a href="javascript:void(0)">播客</a></li> <li><a href="javascript:void(0)">博客</a></li> <li><a href="javascript:void(0)">相册</a></li> <li><a href="javascript:void(0)">关于</a></li> <li><a href="javascript:void(0)">帮助</a></li> </ul>
<script> var ul = document.getElementById("list"); var lis = ul.getElementsByTagName("li"); //不关心层级 只找指定标签 //缺点: 如果内部还有li 也会找到 var nodes = ul.childNodes; //子节点 只找子级 //缺点: 除了我们想要的元素节点 还会获取到其他节点 var children = ul.children;//子元素
</script>
childNodes是DOM标准中规定的方法 获取节点的方式所有浏览器都支持
children不是DOM标准中规定的方法 因为很常用所有浏览器也都支持
在实际应用中,基本都是用children。
获取下一个兄弟节点
nextSibling:下一个兄弟节点
<input type="text" id="txtName"> <span></span> <input type="text" id="txtPwd"><span></span> <input type="button" id="btn" value="注册"> <script> var txt = document.getElementById("txtName"); var next = txt.nextSibling;// 获取到的是换行,空文本节点 var pwd = document.getElementById("txtPwd"); var next = pwd.nextSibling;// 获取到的是span元素,因为两个标签间没有其他节点 </script>
获取下一个兄弟元素
nextElementSibling: 下一个兄弟元素
<input type="text" id="txtName"> <span></span> <script> var txt = document.getElementById("txtName"); var next = txt.nextElementSibling;// 可以获取到span元素,只获取下一个兄弟元素,忽略非元素类型的节点 </script>
获取父节点
parentNode: 获取元素的父节点,父节点肯定是一个元素
<div id = "box"> <img src="1.jpg" id="img"/> </div> <script> var img = document.getElementById("img"); var parent = img.parentNode; //获取到的就是id为box的div元素 </script>
节点的获取我就先介绍到这里,关于兼容性的问题我会再做补充。
下面看一下如何进行节点的样式操作。
获取样式
- 通过style只能获取行内样式
- 获取的样式如果有单位,获取到的样式中也会带单位,类型是一个字符串
设置样式
1、通过style设置样式
- 通过style设置的是行内样式
- 如果样式需要单位,设置时也需要把单位带上
div{ width:100px; height:100px; } <div id="box"></div> var box = document.getElementById("box"); consloe.log(box.style.width);// 打印的是空字符串,因为只能获取行内样式 box.style.width = "300px";// 设置的是行内样式,而且这里必须带单位 console.log(box.style.width);// 打印的是“300px“/
2、通过类名设置样式
.b{ width:100px; height:100px; background-color:red; } <div id="box"></div> var box = document.getElementById("box"); // 通过类名设置样式 两种方式 box.className = "b"; box.setAttribute("class","b");
下面介绍事件绑定
绑定事件
事件三要素: 事件源 事件 事件处理程序
事件源.事件 = function(){ // 事件处理程序 } <img src="pic.jpg" id="img"/> var img = document.getElementById("img"); img.onclick = function(){ ... }
img是事件源 事件是点击onclick 事件处理程序是函数体中的内容
下面为常用事件总结
属性 |
描述 |
Onblur |
元素失去焦点。 |
Onchange |
域的内容被改变。 |
Onclick |
当用户点击某个对象时调用的事件句柄。 |
ondblclick |
当用户双击某个对象时调用的事件句柄。 |
Onfocus |
元素获得焦点。 |
onkeydown |
某个键盘按键被按下。 |
onkeypress |
某个键盘按键被按下并松开。 |
Onkeyup |
某个键盘按键被松开。 |
Onload |
一张页面或一幅图像完成加载。 |
onmousedown |
鼠标按钮被按下。 |
onmousemove |
鼠标被移动。 |
onmouseout |
鼠标从某元素移开。 |
onmouseover |
鼠标移到某元素之上。 |
onmouseup |
鼠标按键被松开。 |
Onreset |
重置按钮被点击。 |
Onresize |
窗口或框架被重新调整大小。 |
Onunload |
用户退出页面。 |
节点操作
节点操作就5种形式,克隆节点、添加节点、插入节点、移除节点和创建节点。
克隆节点 - cloneNode()
element.cloneNode(): 复制element节点
参数:布尔值,
true代表深层克隆,把当前节点和内部所有节点都复制一份
false代表浅层克隆,只复制当前节点
<div id="father"> <div id="son"><div/> </div> var father = document.getElementById("father"); var son = document.getElementById("son"); var clone = son.cloneNode(true);// 把son这个div复制一份 复制出来的clone和son没有任何关系了
添加节点 - appendChild()
father.appendChild(son):将son节点追加到father内部的最后位置
<div id="father"> <div id="son"><div/> </div> <div id="demo"></div> var father = document.getElementById("father"); var demo = document.getElementById("demo"); var clone = demo.cloneNode(true);// 将demo克隆一份 father.appendChild(clone);// 将克隆出来的clone追加到father中 // 此时页面结构应该为 <div id="father"> <div id="son"><div/> <div id="demo"></div> </div> <div id="demo"></div>
//追加克隆节点对原节点不会产生影响
//如果代码如下 则会将demo节点直接移动到father节点下
father.appendChild(demo);// demo是页面上存在的节点
// 此时页面结构应该为
<div id="father">
<div id="son"><div/>
<div id="demo"></div>
</div>
插入节点 - insertBefore()
father.inserBefore(son1,son2): 将son1插入到father节点下的son2前面
<div id="father"> <div id="son"><div/> </div> <div id="demo"></div> var father = document.getElementById("father"); var son = document.getElementById("son"); var demo = document.getElementById("demo"); father.inserBefore(son,demo);//会直接将demo节点移动到father下的son前面
插入克隆出来的节点也不会对原节点产生影响
移除节点 - removeChild()
father.removeChild(son): 将father下的son节点移除
<div id="father"> <div id="son"><div/> </div> var father = document.getElementById("father"); var son = document.getElementById("son"); father.removeChild(son);// 直接将son节点删除
创建节点
document.write()
特点:只能被document调用,而且会覆盖页面上原有内容
document.write("<a href="http://www.baidu.com">百度</a>")
// 可以在页面上创建一个a标签,而且会覆盖页面上原有的所有内容
innerHtml()
特点:往页面添加html标签,可以限定范围
<div id="box"></div> var box = document.getElementById("box"); box.innerHtml = "<a href="http://www.baidu.com">百度</a>"; // 追加后的结构为 <div id="box"> <a href="http://www.baidu.com">百度</a> </div>
createElement()
特点:动态创建标签,添加到页面需要配合appendChild使用。
<div id="box"></div> var box = document.getElementById("box"); var input = document.createElement("input"); input.type = "text"; box.appendChild(input);
DOM的基本操作就到此为止了,如果对你有所帮助就给本文点个赞吧O(∩_∩)O
以上是关于一篇文章搞懂DOM的主要内容,如果未能解决你的问题,请参考以下文章