18 【节点的关系和内部操作】
18 【节点的关系和内部操作】
1.节点的关系
![](https://i0.hdslb.com/bfs/album/a8821cf029e2fa7e8eb3db98db0c675360d99ae4.png)
关系 | 考虑所有结点 |
---|---|
子节点 | childNodes |
父节点 | parentNode |
第一个子节点 | firstChild |
最后一个子节点 | lastChild |
前一个兄弟节点 | previousSibling |
后一个兄弟节点 | nextSibling |
【注意:文本节点也属于节点】
DOM 中,文本节点也属于节点,在使用节点的关系时一定要注意。
在标准的 W3C 规范中,空白文本节点也应该算作节点,但是在 IE8 及以前的浏览器中会有一定的兼容问题,它们不把空白文本节点当作节点。
【排除文本节点的干扰】
从 IE9 开始支持一些 “只考虑元素节点” 的属性。
如果考虑兼容性,可以通过后面的函数封装来实现。
关系 | 考虑所有结点 | 只考虑元素节点 |
---|---|---|
子节点 | childNodes | children |
父节点 | parentNode | 同 |
第一个子节点 | firstChild | firstElementChild |
最后一个子节点 | lastChild | lastElementChild |
前一个兄弟节点 | previousSibling | previousElementSibling |
后一个兄弟节点 | nextSibling | nextElementSibling |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box">
<p>我是段落A</p>
<p id="para">我是段落B</p>
<p>我是段落C</p>
</div>
<script>
var box = document.getElementById('box');
var para = document.getElementById('para');
// 所有子节点
console.log(box.childNodes);
// 所有的元素子节点(IE9开始兼容)
console.log(box.children);
console.log(box.children.para);
// 第一个子节点
console.log(box.firstChild);
console.log(box.firstChild.nodeType);
// 第一个元素子节点(IE9开始兼容)
console.log(box.firstElementChild);
// 最后一个子节点
console.log(box.lastChild);
console.log(box.lastChild.nodeType);
// 最后一个元素子节点(IE9开始兼容)
console.log(box.lastElementChild);
// 父节点
console.log(para.parentNode);
// 前一个兄弟节点
console.log(para.previousSibling);
// 前一个元素兄弟节点(IE9开始兼容)
console.log(para.previousElementSibling);
// 后一个兄弟节点
console.log(para.nextSibling);
// 后一个元素兄弟节点(IE9开始兼容)
console.log(para.nextElementSibling);
</script>
</body>
</html>
- 结果
![](https://i0.hdslb.com/bfs/album/e66b1d9963a26d2d560157c8e592ae5f810f98f4.png)
注意:文本也算作节点(如图选中空白部分)
![](https://i0.hdslb.com/bfs/album/1ce25ef2816cd948a18d0f67889bc21f49158cd5.png)
2.如何改变元素节点中的内容
改变元素节点中的内容可以使用两个相关属性。
innerHTML
innerText
innerHTML
属性能以 HTML 语法设置节点中的内容。
innerText
属性只能以纯文本的形式设置节点中的内容。
- innerHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
oBox.innerHTML = 'ds';
</script>
</body>
</html>
- innerHTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
// 注意:此处的 HTML 字符串不允许换行!
oBox.innerHTML = '<ul><li>牛奶</li><li>咖啡</li></ul>';
</script>
</body>
</html>
![](https://i0.hdslb.com/bfs/album/223c5c2407e51dee586d3d01e19d28424c798120.png)
- innerText
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
oBox.innerText = 'ds';
</script>
</body>
</html>
- innerText
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script>
var oBox = document.getElementById('box');
oBox.innerText = '<ul><li>牛奶</li><li>咖啡</li></ul>';
</script>
</body>
</html>
![](https://i0.hdslb.com/bfs/album/c427b3475ca842a957605d4af2cd3c1309d960e6.png)
3.如何改变元素节点的CSS样式
3.1 控制样式属性
应用【修改样式】,通过修改行内样式 style
属性,实现对样式的动态修改。
应用【修改样式】,通过修改行内样式 style
属性,实现对样式的动态修改。
改变元素节点的 CSS 样式需要使用这样的语句:
oBox.style.backgroundColor = 'red';
oBox.style.backgroundImage = 'url(images/1.jpg)';
oBox.style.fontSize = '32px';
【注意事项】
- CSS 属性要写成 “驼峰” 形式
- CSS 属性值要设置成完整形式
- 注意写单位
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div class="box" id="box">
你好
</div>
<script>
var oBox = document.getElementById('box');
oBox.style.backgroundColor = 'rgb(100, 200, 123)';
oBox.style.backgroundColor = '#f80';
oBox.style.backgroundImage = 'url(https://www.imooc.com/static/img/index/logo-recommended.png)';
oBox.style.backgroundSize = 'contain';
oBox.style.fontSize = '50px';
</script>
</body>
</html>
JS 修改的 CSS 样式,属于行内式,优先级最高!所以可以覆盖原有的样式。
3.2 操作类名(className) 操作CSS
如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>练习 - 修改样式</title>
<style>
.pink {
background: pink;
color: hotpink;
}
</style>
</head>
<body>
<div class="box">随便一些文本内容</div>
<script>
// 获取 DOM 节点
const box = document.querySelector('.intro')
box.className = 'pink'
</script>
</body>
</html>
注意:
1.由于class是关键字, 所以使用className去代替
2.className是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名
3.3 通过 classList 操作类控制CSS
className
属性用来读写当前元素节点的class
属性。它的值是一个字符串,每个class
之间用空格分割。
classList
属性返回一个类似数组的对象,当前元素节点的每个class
就是这个对象的一个成员。
// HTML 代码 <div class="one two three" id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className
// "one two three"
div.classList
// {
// 0: "one"
// 1: "two"
// 2: "three"
// length: 3
// }
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
定义及用法
- classList 属性返回元素类名.
- 该属性用于在元素中添加, 移除及切换 CSS 类.
- classList 是只读属性.
语法
element.classList
属性
length:
只读属性, 返回列表中类的长度.
方法
- 为元素添加类:
element.classList.add(class1, class2, …);
add(class1, class2, ...) * 在元素中添加一个或多个类名. * 若指定类名已存在, 则不添加.
查看元素是否存在类:
element.classList.contains(class);
contains(class) * 判断类名是否存在. * 返回布尔值: true/false.
3. 获取元素的第 index 个类名(索引为 index ):
element.classList.item(index);
item(index) * 返回类名在元素中的索引值, 索引从 0 开始. * 如果不在索引区间内, 返回 null.
- 移除类
element.classList.remove(“mystyle”); // 单个移除 element.classList.remove(“mystyle”, “anotherClass”, “thirdClass”); // 多个移除
remove(class1, class2, ...) * 在元素中删除一个或多个类名. * 若指定类名不存在, 不会报错.
- 为元素切换类:
element.classList.toggle(“newClassName”);
toggle(class, true|false) * 在元素中切换类名. * 第一个在参数为在元素中移除的类名, 并返回 false. * 如果该类名不存在, 则会在元素中添加类名, 并返回 true. * 第二参数可选, 是布尔值, 用于设置元素是否强制添加或移除类, 不管该类是否存在. * 注意: Internet Explorer 或 Opera 12 及其更早版本不支持第二个参数。
案例
var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果 myCssClass 不存在就加入,否则移除
div.classList.contains('myCssClass'); // 返回 true 或者 false
div.classList.item(0); // 返回第一个 Class
div.classList.toString();
下面比较一下,className
和classList
在添加和删除某个 class 时的写法。
var foo = document.getElementById('foo');
// 添加class
foo.className += 'bold';
foo.classList.add('bold');
// 删除class
foo.classList.remove('bold');
foo.className = foo.className.replace(/^bold$/, '');
toggle
方法可以接受一个布尔值,作为第二个参数。如果为true
,则添加该属性;如果为false
,则去除该属性。
el.classList.toggle('abc', boolValue);
// 等同于
if (boolValue) {
el.classList.add('abc');
} else {
el.classList.remove('abc');
}
classList
属性指向一个类似数组的对象,该对象的length
属性(只读)返回当前元素的class
数量。
classList
对象有下列方法。
add()
:增加一个 class。remove()
:移除一个 class。contains()
:检查当前元素是否包含某个 class。toggle()
:将某个 class 移入或移出当前元素。item()
:返回指定索引位置的 class。toString()
:将 class 的列表转为字符串。
3.4 通过 getComputedStyle 操作伪元素
CSS 伪元素是通过 CSS 向 DOM 添加的元素,主要是通过:before
和:after
选择器生成,然后用content
属性指定伪元素的内容。
下面是一段 HTML 代码。
<div id="test">Test content</div>
CSS 添加伪元素:before
的写法如下。
#test:before {
content: 'Before ';
color: #FF0;
}
节点元素的style
对象无法读写伪元素的样式,这时就要用到window.getComputedStyle()
。JavaScript 获取伪元素,可以使用下面的方法。
var test = document.querySelector('#test');
var result = window.getComputedStyle(test, ':before').content;
var color = window.getComputedStyle(test, ':before').color;
此外,也可以使用 CSSStyleDeclaration 实例的getPropertyValue
方法,获取伪元素的属性。
var result = window.getComputedStyle(test, ':before')
.getPropertyValue('content');
var color = window.getComputedStyle(test, ':before')
.getPropertyValue('color');
4.如何改变元素节点的HTML属性
标准 W3C 属性,如 src
、href
、title
、alt
等等,只需要直接打点进行更改即可。
oImg.src = 'images/2.jpg';
【案例】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<img src="images/1.jpg" id="pic">
<a href="http://www.baidu.com" id="link">
去百度
</a>
<script>
var oPic = document.getElementById('pic');
var oLink = document.getElementById('link');
oPic.src = 'images/2.jpg';
oLink.href = 'http://www.imooc.com';
oLink.innerText = '去慕课网';
</script>
</body>
</html>
对于不符合 W3C 标准的属性,要使用 setAttribute()
和 getAttribute()
来设置、读取。
oBox.setAttribute('data-n', 10);
var n = oBox.getAttribute('data-n');
alert(n);
HTML 的自定义属性,主要用途就是与 JS 配合方便实现一些效果。
【案例】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="box"></div>
<script>
var box = document.getElementById('box');
box.setAttribute('data-n', 10);
var n = box.getAttribute('data-n');
alert(n);
</script>
</body>
</html>
![](https://i0.hdslb.com/bfs/album/0a2b76b0a888113ea0b1af90b03ca09fac264dea.png)
这里只是简单说一下,后面会详细讲解属性的操作
5.如何改变表单元素的状态
表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框
正常的有属性有取值的跟其他的标签属性没有任何区别
获取:DOM对象.属性名
设置:DOM对象.属性名= 新值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" value="请输入">
<button disabled>按钮</button>
<input type="checkbox" name="" id="" class="agree">
<script>
// 1. 获取元素
let input = document.querySelector('input')
// 2. 取值或者设置值 得到input里面的值可以用 value
// console.log(input.value)
input.value = '小米手机'
input.type = 'password'
// 2. 启用按钮
let btn = document.querySelector('button')
// disabled 不可用 = false 这样可以让按钮启用
btn.disabled = false
// 3. 勾选复选框
let checkbox = document.querySelector('.agree')
checkbox.checked = false
</script>
</body>
</html>