【节点的关系和内部操作】

节点的关系

关系 考虑所有结点
子节点 childNodes
父节点 parentNode
第一个子节点 firstChild
最后一个子节点 lastChild
前一个兄弟节点 previousSibling
后一个兄弟节点 nextSibling

【注意:文本节点也属于节点】

DOM 中,文本节点也属于节点,在使用节点的关系时一定要注意。

在标准的 W3C 规范中,空白文本节点也应该算作节点,但是在 IE8 及以前的浏览器中会有一定的兼容问题,它们不把空白文本节点当作节点。

【排除文本节点的干扰】

从 IE9 开始支持一些 “只考虑元素节点” 的属性。

如果考虑兼容性,可以通过后面的函数封装来实现。

关系 考虑所有结点 只考虑元素节点
子节点 childNodes children
父节点 parentNode
第一个子节点 firstChild firstElementChild
最后一个子节点 lastChild lastElementChild
前一个兄弟节点 previousSibling previousElementSibling
后一个兄弟节点 nextSibling nextElementSibling
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!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>
  • 结果

注意:文本也算作节点(如图选中空白部分)

如何改变元素节点中的内容

改变元素节点中的内容可以使用两个相关属性。

  • innerHTML
  • innerText

innerHTML 属性能以 HTML 语法设置节点中的内容。

innerText 属性只能以纯文本的形式设置节点中的内容。

  • innerHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!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>
  • innerText
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!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>

如何改变元素节点的CSS样式

控制样式属性

应用【修改样式】,通过修改行内样式 style 属性,实现对样式的动态修改。

应用【修改样式】,通过修改行内样式 style 属性,实现对样式的动态修改。

改变元素节点的 CSS 样式需要使用这样的语句:

  • oBox.style.backgroundColor = 'red';
  • oBox.style.backgroundImage = 'url(images/1.jpg)';
  • oBox.style.fontSize = '32px';

【注意事项】

  • CSS 属性要写成 “驼峰” 形式
  • CSS 属性值要设置成完整形式
  • 注意写单位
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!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 样式,属于行内式,优先级最高!所以可以覆盖原有的样式。

操作类名(className) 操作CSS

如果修改的样式比较多,直接通过style属性修改比较繁琐,我们可以通过借助于css类名的形式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!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是使用新值换旧值, 如果需要添加一个类,需要保留之前的类名

通过 classList 操作类控制CSS

className属性用来读写当前元素节点的class属性。它的值是一个字符串,每个class之间用空格分割。

classList属性返回一个类似数组的对象,当前元素节点的每个class就是这个对象的一个成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 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

属性

1
2
length:
只读属性, 返回列表中类的长度.

方法

  1. 为元素添加类:

element.classList.add(class1, class2, …);

1
2
3
add(class1, class2, ...)
* 在元素中添加一个或多个类名.
* 若指定类名已存在, 则不添加.
  1. 查看元素是否存在类:

    element.classList.contains(class);

    1
    2
    3
    contains(class)
    * 判断类名是否存在.
    * 返回布尔值: true/false.

​ 3. 获取元素的第 index 个类名(索引为 index ):

element.classList.item(index);

1
2
3
item(index)
* 返回类名在元素中的索引值, 索引从 0 开始.
* 如果不在索引区间内, 返回 null.
  1. 移除类

element.classList.remove(“mystyle”); // 单个移除
element.classList.remove(“mystyle”, “anotherClass”, “thirdClass”); // 多个移除

1
2
3
remove(class1, class2, ...)
* 在元素中删除一个或多个类名.
* 若指定类名不存在, 不会报错.
  1. 为元素切换类:

element.classList.toggle(“newClassName”);

1
2
3
4
5
6
toggle(class, true|false)
* 在元素中切换类名.
* 第一个在参数为在元素中移除的类名, 并返回 false.
* 如果该类名不存在, 则会在元素中添加类名, 并返回 true.
* 第二参数可选, 是布尔值, 用于设置元素是否强制添加或移除类, 不管该类是否存在.
* 注意: Internet ExplorerOpera 12 及其更早版本不支持第二个参数。

案例

1
2
3
4
5
6
7
8
9
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();

下面比较一下,classNameclassList在添加和删除某个 class 时的写法。

1
2
3
4
5
6
7
8
9
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,则去除该属性。

1
2
3
4
5
6
7
8
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 的列表转为字符串。

通过 getComputedStyle 操作伪元素

CSS 伪元素是通过 CSS 向 DOM 添加的元素,主要是通过:before:after选择器生成,然后用content属性指定伪元素的内容。

下面是一段 HTML 代码。

1
<div id="test">Test content</div>

CSS 添加伪元素:before的写法如下。

1
2
3
4
#test:before {
content: 'Before ';
color: #FF0;
}

节点元素的style对象无法读写伪元素的样式,这时就要用到window.getComputedStyle()。JavaScript 获取伪元素,可以使用下面的方法。

1
2
3
4
var test = document.querySelector('#test');

var result = window.getComputedStyle(test, ':before').content;
var color = window.getComputedStyle(test, ':before').color;

此外,也可以使用 CSSStyleDeclaration 实例的getPropertyValue方法,获取伪元素的属性。

1
2
3
4
var result = window.getComputedStyle(test, ':before')
.getPropertyValue('content');
var color = window.getComputedStyle(test, ':before')
.getPropertyValue('color');

如何改变元素节点的HTML属性

标准 W3C 属性,如 srchreftitlealt 等等,只需要直接打点进行更改即可。

oImg.src = 'images/2.jpg';

【案例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!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() 来设置、读取。

1
2
3
oBox.setAttribute('data-n', 10);
var n = oBox.getAttribute('data-n');
alert(n);

HTML 的自定义属性,主要用途就是与 JS 配合方便实现一些效果。

【案例】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!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>

这里只是简单说一下,后面会详细讲解属性的操作

如何改变表单元素的状态

表单很多情况,也需要修改属性,比如点击眼睛,可以看到密码,本质是把表单类型转换为文本框

正常的有属性有取值的跟其他的标签属性没有任何区别

获取:DOM对象.属性名

设置:DOM对象.属性名= 新值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!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>
Document 节点 节点的增删改查