DOM 操作
DOM
一、DOM介绍
Document Object Model 文档对象模型
DOM 对象:
属性: 获取值和赋值
方法:赋值方法和调用方法
DOM 树 : 在DOM树中一切都是节点,所有的节点都是对象。
二、DOM 对象的获取:
DOM 三步走:
1、获取事件源:引发后续事件的html标签。
2、事件绑定:js 定义好的, 事件源.onclick = functioan(){ 事件驱动 }。
3、事件驱动(业务逻辑):对样式和html的操作,也就是DOM。
(1)获取事件源
| 获取Document对象 |
console.log(document); |
| 获取html对象 |
document.documentElement; |
| 获取body对象 |
document.body; |
3种方式获取 body 对象中的事件源:(DOM节点的获取)
|
div#box.box <div id="box" class="box"></div> |
||
| 通过 id 获取 |
var div1 = document.getElementById("box"); |
id 是唯一的,可以直接拿到(常用) |
| 通过 类 获取 |
var arr = document.getElementsByClassName("box")[0]; |
获取到的是数组,通过[i] 索引获取 |
| 通过 标签 获取 |
var arr = document.getElementsByTagName("div")[0]; |
获取到的是数组,通过[i] 索引获取 |
(2)事件绑定
方式一:直接绑定匿名函数 (常用)
<div id="box1" ></div> <script type="text/javascript"> var div1 = document.getElementById("box1");
//绑定事件的第一种方式 div1.onclick = function () { alert("我是弹出的内容"); } </script>
方式二:先单独定义函数,再绑定
<div id="box1" ></div>
<script type="text/javascript">
var div1 = document.getElementById("box1");
//绑定事件的第二种方式
div1.onclick = fn; //注意,这里是fn,不是fn()。fn()指的是返回值。
//单独定义函数
function fn() {
alert("我是弹出的内容");
}
</script>
方式三:行内绑定
<!--行内绑定-->
<div id="box1" onclick="fn()"></div>
<script type="text/javascript">
function fn() {
alert("我是弹出的内容");
}
</script>
| 事件 | 说明 |
| onclick |
鼠标单击 |
| ondblclick |
鼠标双击 |
| onkeyup |
按下并释放键盘上的一个键时触发 |
| onchange |
文本内容或下拉菜单中的选项发生改变 |
| onfoncus |
获得焦点,表示文本框等获得鼠标光标 |
| onblur |
失去焦点,表示文本框等失去鼠标光标 |
| onmouseover |
鼠标悬停,即鼠标停留在图片等所在的上方;穿过父元素或子元素的时候调用 |
| onmouseout |
鼠标移除,即离开图片等所在的区域; |
| onmouseenter |
穿过父元素的时候调用 |
| onmouseleave |
|
| onload |
网页文档加载事件,当页面加载(文本和图片)完毕后,触发onload事件 , 因此,js 代码写在onload 事件里可以保证,代码的有效性。 |
| onunload |
关闭网页时 |
| onsubmit |
表单提交时 |
| onreset |
重置表单时 |
(3)事件驱动程序
主要是指操作标签的属性和样式。
<style>
#box {
width: 100px;
height: 100px;
background-color: pink;
cursor: pointer;
}
</style>
</head>
<body>
<div id="box" ></div>
<script type="text/javascript">
var oDiv = document.getElementById("box");
//点击鼠标时,原本粉色的div变大了,背景变红了
oDiv.onclick = function () {
oDiv.style.width = "200px"; //属性值要写引号
oDiv.style.height = "200px";
oDiv.style.backgroundColor = "red"; //属性名是backgroundColor,不是background-Color
}
</script>
上方代码的注意事项:
- 在js里写属性值时,要用引号
- 在js里写属性名时,是backgroundColor,不是CSS里面的background-Color。记得所有的像css属性的text-*,line-*、backgroun-*等在js中都写成驼峰
注意 onload事件 :
<script></script>中的代码,原则上是放在任何位置都可以,但是里面的代码如果涉及到的内容未被加载,则 js 也不能顺利执行,如下示例:
<script type="text/javascript">
window.onload = function () {
console.log("小马哥"); //等页面加载完毕时,打印字符串
}
</script>
有一点我们要知道:js的加载是和html同步加载的。因此,如果使用元素在定义元素之前,容易报错。这个时候,onload事件就能派上用场了,我们可以把使用元素的代码放在onload里,就能保证这段代码是最后执行。
建议是:整个页面上所有元素加载完毕在执行js内容。所以,window.onload可以预防使用标签在定义标签之前。
应用1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
.top-banner{
/*position: relative;*/
background-color: rgb(230, 15, 82);
}
.top-banner .w{
width: 1190px;
position: relative;
margin: 0 auto;
}
.top-banner .banner{
display: block;
width: 100%;
height: 80px;
background: url('./close.jpg') no-repeat center 0;
}
.top-banner .close{
position: absolute;
right: 0;
top:0;
text-decoration: none;
color: white;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
}
.hide{
display: none;
}
</style>
</head>
<body>
<div class="top-banner" id="topBanner">
<div class="w">
<a href="#" class="banner"></a>
<a href="#" class="close" id="closeBanner">x</a>
</div>
</div>
<script type="text/javascript">
// /需求:点击案例,隐藏盒子。
//思路:点击a链接,让top-banner这个盒子隐藏起来(加隐藏类名)。
window.onload = function(){
// /1.获取事件源和相关元素
var closeBanner = document.getElementById('closeBanner');
var topBanner = document.getElementById('topBanner');
//2.绑定事件
closeBanner.onclick = function(){
//3.书写事件驱动程序
//类控制
//topBanner.className += ' hide';//保留原类名,添加新类名
//topBanner.className = 'hide';
//替换旧类名
topBanner.style.display = 'none';
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script>
//window.onload页面加载完毕以后再执行此代码
window.onload = function () {
//需求:鼠标放到img上,更换为另一张图片,也就是修改路径(src的值)。
//步骤:
//1.获取事件源
//2.绑定事件
//3.书写事件驱动程序
//1.获取事件源
var img = document.getElementById("box");
//2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件)
img.onmouseover = function () {
//3.书写事件驱动程序(修改src)
img.src = "image/jd2.png";
// this.src = "image/jd2.png";
}
//1.获取事件源
var img = document.getElementById("box");
//2.绑定事件(悬停事件:鼠标进入到事件源中立即出发事件)
img.onmouseout = function () {
//3.书写事件驱动程序(修改src)
img.src = "image/jd1.png";
}
}
</script>
</head>
<body>
<img id="box" src="image/jd1.png" style="cursor: pointer;border: 1px solid #ccc;"/>
</body>
</html>
三、对 样式属性 的操作
更改的是CSS中的属性设置,只是在内存里的,刷新后还是原来的
<body>
<div class="box" id="wrap" style=""></div>
<p>alex</p>
<script>
var oDiv = document.getElementById('wrap');
oDiv.onclick = function() {
oDiv.style.backgroundColor = 'green'; // backgroundColor 没有中间的线
oDiv.style.width = '400px'; //属性要添加引号
oDiv.style.float = 'left';
}
</script>
</body>
四、对 标签属性 的操作
如:id class src alt href title type name
标签属性是对标签中的属性直接进行操作,其中, class 为 className
刷新后还是原来的值.
<body>
<div class="box"></div>
<img src="./images/购物车.png" width="100" alt="" id="shop">
<script>
// 用于判断 鼠标是否悬浮 默认为真
var isHover = true;
document.getElementById('shop').onclick = function() {
if (isHover) {
this.src = './images/购物车-hover.png';
this.className = 'app';
this.alt = '哈哈哈';
this.title = '哈哈哈';
this.id = 'app';
isHover = false; //操作一次改变一次值
}else{
this.src = './images/购物车.png';
isHover = true;
}
}
</script>
</body>
示例:
需求:对某标签的 class 添加类名 "hidden", (因为好多的需求,都需要通过控制类名来添加某些属性)
追加类名: this.className += "hidden";
五、对 值 的操作
主要是针对:
(1)input表单中的 value 值,
(2)标签中的 text 文本内容,如 <p>世界</p>,对“世界”文本进行操作
(3)标签内的所有节点,选中的标签中的左右内容
| .innerText |
只获取文本 |
= 可以替换内容 |
| .innerHTML |
获取文本和标签 (获取的是所有的节点,包括换行 空格等) |
将HTML解析成文本 可用于追加内容 +=" " |
| .value |
主要是针对 input 标签中的value值 |
<body>
<button id="btn"> 隐藏 </button>
<div class="box">
<div class="child" id="child"></div>
</div>
<input type="text" id="user" value = 'wusir'>
<script>
var oChild = document.getElementById('child'); //这个事件操作是异步(不会阻塞 不等待)的
document.getElementById('btn').onclick = function() {
// oChild.style.display = 'none';
oChild.className +=' hidden'; // 追加类名hidden, class="child hidden"
console.log(oChild.className);
console.log(this.innerText); //仅获取文本
console.log(this.innerHTML); //获取的是所有节点(包括换行 空格 标签等)
this.innerHTML += '<span>了么</span>'; // 添加的标签可以被解析,结果是:隐藏了么
this.innerText += '<span>了么</span>'; // 标签当做文本进行了添加,结果:隐藏<span>了么</span>
}
document.getElementById('user').value = 'alex';
</script>
</body>
六、DOM的节点操作(重要)
1、DOM树:

上图可知,在HTML当中,一切都是节点:(非常重要)
-
-
元素节点:HMTL标签。
-
文本节点:标签中的文字(比如标签之间的空格、换行)
-
属性节点::标签的属性。
-
整个html文档就是一个文档节点。所有的节点都是Object
2、DOM节点的获取
DOM节点的获取方式其实就是获取事件源的方式
操作元素节点,必须首先找到该节点。有三种方式可以获取DOM节点:
var div1 = document.getElementById("box1"); //方式一:通过id获取单个标签
var arr1 = document.getElementsByTagName("div1"); //方式二:通过 标签名 获得 标签数组,所以有s
var arr2 = document.getElementsByClassName("hehe"); //方式三:通过 类名 获得 标签数组,所以有s
既然方式二、方式三获取的是标签数组,那么习惯性是先遍历之后再使用。
特殊情况:数组中的值只有1个。即便如此,这一个值也是包在数组里的。这个值的获取方式如下:
document.getElementsByTagName("div1")[0]; //取数组中的第一个元素
document.getElementsByClassName("hehe")[0]; //取数组中的第一个元素
3、DOM访问关系的获取
DOM的节点并不是孤立的,因此可以通过DOM节点之间的相对关系对它们进行访问。如下:

节点的访问关系,是以属性的方式存在的。
JS中的父子兄访问关系:

这里我们要重点知道parentNode和children这两个属性的用法。
| 所有子节点 | 节点.childrenNodes |
获取子节点 亲儿子 (包括元素节点、所有属性、文本节点等) 火狐 谷歌 等高版本把换行也会看做是子节点 |
| 节点.children (用的最多) |
获取所有的 子节点元素的集合 (子元素节点的集合)
虽然不是标准的DOM属性,但它和innerHTML方法一样,得到了几乎所有浏览器的支持。
|
|
| 父节点 | 节点.parentNode |
获取的是 父亲节点 |
| 兄弟节点
|
节点.nextSibling |
下一个节点(包含标签、空格、换行节点等) • 火狐、谷歌、IE9+版本:都指的是前一个节点(包括标签、空文档和换行节点)。 • IE678版本:指前一个元素节点(标签)。 |
| 节点.nextElementSibling |
下一个元素节点 • 火狐、谷歌、IE9+版本:都指的是下一个元素节点(标签)。 |
|
|
节点.previousSibling |
前一个节点 • 火狐、谷歌、IE9+版本:都指的是前一个节点(包括标签、空文档和换行节点)。 • IE678版本:指前一个元素节点(标签)。 |
|
|
节点.previousElementSibling |
前一个元素节点 • 火狐、谷歌、IE9+版本:都指的是前一个元素节点(标签)。 |
|
| 子节点 |
节点.firstChild |
第一个节点 • 火狐、谷歌、IE9+版本:都指的是第一个子节点(包括标签、空文档和换行节点)。 • IE678版本:指第一个子元素节点(标签)。 |
|
节点.firstElementChild |
第一个子元素节点 • 火狐、谷歌、IE9+版本:都指的是第一个子元素节点(标签)。 |
|
|
节点.lastChild |
最后一个子节点 • 火狐、谷歌、IE9+版本:都指的是最后一个子节点(包括标签、空文档和换行节点)。 • IE678版本:指最后一个子元素节点(标签)。 |
|
|
节点.lastElementChild |
最后一个子元素节点 • 火狐、谷歌、IE9+版本:都指的是最后一个子元素节点(标签)。 |
4、nodeType
• nodeType == 1 表示的是元素节点(标签) (记住) 元素就是标签
• nodeType == 2 表示的是属性节点 (了解)
• nodeType == 3 表示的是文本节点 (了解)
5、节点操作( DOM的创建和销毁 非常重要)
节点的访问关系属于属性。节点的操作都是函数(方法)。
| 创建节点 | document.createElment("div"); 标签名 |
创建节点(元素节点) 有返回值 |
| 插入节点 | 父节点.appendChild(新的子节点); |
将子元素追加都父元素中 |
| 父节点.insertBefore(新的子节点,作为参考的子节点); |
• 在参考的节点前插入新的节点 • 如果参考节点为null,那么将在父节点最后插入一个子节点 |
|
| 删除节点 |
父节点.removeChild(子节点);
|
用父节点删除子节点,必须制定是删除的哪个子节点 如果想删除自己: node1.parentNode.removeChild(node1);
|
|
复制节点 (克隆节点) |
要复制的节点.cloneNode(true);
|
不带参数/带参数false:只复制节点本身,不复制子节点。 |
要复制的节点.cloneNode(true);
|
带参数true:既复制节点本身,也复制其所有的子节点。 |
6、设置节点的属性
统一拿下面的标签来举例:
<body>
<img src="images/1.jpg" class="image-box" title="美女图片" alt="地铁一瞥" id="a1">
<script type="text/javascript">
var myNode = document.getElementsByTagName("img")[0];
...
...
</script>
</body>
| 名称 |
语法 |
说明 | 举例 |
| 获取节点属性值 |
元素节点 . 属性; 元素节点 [属性]; |
直接操作标签 (推荐使用) |
console.log(myNode.className);
console.log(myNode["title"])
|
|
元素节点.getAtrribute("属性名称"); |
把标签作为DOM节点 |
console.log(myNode.getAttribute("class")); //注意是class,不是className
|
|
| 设置节点属性值 |
元素节点 . 属性 = "新的属性值"; |
(推荐使用) |
myNode.src = "images/2.jpg" //修改src的属性值
myNode.className = "image2-box"; //修改class的name
|
|
元素节点 . setAtrribute("属性名","新的属性值"); |
myNode.setAttribute("src","images/3.jpg");
myNode.setAttribute("class","image3-box");
|
||
| 删除节点 |
元素节点 . removeAtrribute(属性名) |
myNode.removeAttribute("class");
myNode.removeAttribute("id");
|
七、控制元素 显示/隐藏
• 网页中 频繁 的切换 建议使用
1、控制样式属性:.style.display = none | block;
2、控制标签属性:添加className,对类属性 添加 移除
前两种方法问题,初始化的时候有渲染,渲染一次之后,后面操作方便。
• 网页中 少量 的切换建议使用(如注册 登录)
3、对元素 创建和销毁(DOM)
生命周期 创建 销毁


浙公网安备 33010602011771号