7.2 获取 DOM 元素
getElementById
document.getElementById()可以通过元素的 ID 属性获取对应的 DOM 元素。
使用方法如下:
var element = document.getElementById(id);
其中,id 为要获取的元素的 ID 属性的值。getElementById()方法返回一个元素对象,可以用来操作该元素,比如修改其内容或样式,绑定事件等。
例如,假设我们有以下 HTML 代码:
<div id="myDiv">This is my div element.</div>
我们可以使用 getElementById()方法获取这个元素,并修改它的内容和背景颜色:
var myDiv = document.getElementById('myDiv');
myDiv.innerHTML = 'This is my updated div element.';
myDiv.style.backgroundColor = 'red';
上述代码中,首先通过 getElementById()方法获取了 ID 为 myDiv 的元素对象,并保存在 myDiv 变量中。然后,修改了这个元素的内容和背景颜色。 注意点 1: 我们应该让页面中元素的 id 是唯一的,即使不唯一也不会报错,但是 getElementById 方法获取到的是第一个匹配的元素。 注意点 2: 在用 JavaScript 获取 DOM 元素的时候,一定要保证 DOM 元素已经存在,所以要保证 script 标签在 DOM 元素的后面,之后的方法也是类型。
getElementsByTagName
getElementsByTagName()可以通过元素标签名获取对应的 DOM 元素。
使用方法如下:
var elements = document.getElementsByTagName(tagName);
其中,tagName 为要获取的元素的标签名,比如 div、p、ul 等。getElementsByTagName()方法返回一个元素对象数组,可以用来操作这些元素,比如修改它们的内容或样式,绑定事件等。
例如,假设我们有以下 HTML 代码:
<p>This is the first paragraph.</p>
<p>This is the second paragraph.</p>
我们可以使用 getElementsByTagName()方法获取所有的
元素,并修改它们的内容和颜色:
var paragraphs = document.getElementsByTagName('p');
for (var i = 0; i < paragraphs.length; i++) {
paragraphs[i].innerHTML = 'This is a paragraph.';
paragraphs[i].style.color = 'blue';
}
上述代码中,首先通过 getElementsByTagName()方法获取所有的
元素,并保存在 paragraphs 数组中。然后,使用一个循环遍历这些元素,将它们的内容修改为"This is a paragraph.",并将它们的颜色修改为蓝色。
getElementsByClassName
getElementsByClassName 方法是 document 对象的一个方法,用于根据指定的类名获取当前文档中所有符合条件的元素节点,返回的是一个类数组对象,其中每个元素都是一个元素节点对象。
该方法的语法如下:
document.getElementsByClassName(className);
其中,className 是一个字符串,表示要获取元素节点的类名,可以指定一个或多个类名,多个类名之间用空格隔开。
例如,要获取所有类名为 box 的元素节点,可以使用以下代码:
<!DOCTYPE html>
<html>
<head>
<title>getElementsByClassName</title>
<style type="text/css">
.box {
width: 100px;
height: 100px;
background-color: red;
margin: 10px;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<script type="text/javascript">
var boxes = document.getElementsByClassName('box');
console.log(boxes); // 返回一个类数组对象
console.log(boxes.length); // 5
</script>
</body>
</html>
在上面的例子中,getElementsByClassName 方法返回一个类数组对象,其中包含了文档中所有类名为 box 的元素节点。通过 boxes.length 可以获取到符合条件的元素节点个数,也可以通过下标来访问某一个具体的元素节点。 可以指定多个类名来查找元素,这时需要将多个类名用空格分隔。例如,如果我们想获取类名既为 box 又为 red 的元素节点,可以这样写:
<!DOCTYPE html>
<html>
<head>
<title>getElementsByClassName with multiple class names</title>
<style type="text/css">
.box {
width: 100px;
height: 100px;
background-color: red;
margin: 10px;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
</style>
</head>
<body>
<div class="box red"></div>
<div class="box blue"></div>
<div class="box red"></div>
<div class="box"></div>
<div class="box red blue"></div>
<script type="text/javascript">
var boxes = document.getElementsByClassName('box red');
console.log(boxes); // 返回一个类数组对象
console.log(boxes.length); // 3
</script>
</body>
</html>
在上面的例子中,我们在<div>元素中同时添加了 box 和 red 类名,这样这个元素就同时符合这两个类名的条件了。我们调用 document.getElementsByClassName('box red')方法就可以获取到所有同时包含 box 和 red 类名的元素节点了。
querySelector
querySelector 方法是 document 对象的一个方法,用于在文档中查找符合指定 CSS 选择器的第一个元素节点,返回的是一个元素节点对象。
该方法的语法如下:
document.querySelector(selector);
其中,selector 是一个 CSS 选择器,表示要查找的元素节点的样式。selector 可以是任何符合 CSS 规则的字符串,例如标签名、类名、ID 等。下面是使用 querySelector 配合 css 选择器的例子:
<!DOCTYPE html>
<html>
<head>
<title>querySelector demo</title>
</head>
<body>
<div id="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>
<script type="text/javascript">
// 选择第一个类名为box的div元素节点对象
var box1 = document.querySelector('.box');
console.log(box1.innerHTML); // 1
// 选择#main元素节点下的第一个类名为box的div元素节点对象
var box2 = document.querySelector('#main .box');
console.log(box2.innerHTML); // 1
// 选择#main元素节点下第一个类名为box的div元素节点对象
var box3 = document.querySelector('#main .box:first-child');
console.log(box3.innerHTML); // 1
// 选择#main元素节点下奇数位置的第一个类名为box的div元素节点对象
var box4 = document.querySelector('#main .box:nth-child(odd)');
console.log(box4.innerHTML); // 1
// 选择#main元素节点下偶数位置的第一个类名为box的div元素节点对象
var box5 = document.querySelector('#main .box:nth-child(even)');
console.log(box5.innerHTML); // 2
// 选择#main元素节点下偶数位置的第三个类名为box的div元素节点对象
var box5 = document.querySelector('#main .box:nth-child(3)');
console.log(box5.innerHTML); // 3
</script>
</body>
</html>
querySelectorAll
querySelectorAll 方法和 querySelector 方法类似,但是它会返回匹配指定选择器的所有元素,而不是只返回第一个匹配的元素。
querySelectorAll 方法的语法如下:
elementList = parentNode.querySelectorAll(selectors);
注意点: 这里和之前的写法不一样了,把 document 改成了 parentNode,document 其实也是一个 parentNode。所以我们可以知道其实不仅仅是 document 有 querySelectorAll 方法,其他普通的 dom 节点也可以调用这个方法,不同的就是查询的范围,document 是在整个 dom 树上查找,而使用 parentNode 查找则是在其子元素内查找。
请看一下例子:
<!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="main">
<div class="box"><p></p></div>
<div class="box"></div>
<div class="box special"><p>special p</p></div>
<div class="box"></div>
<div class="box special"></div>
</div>
<script>
var boxes = document.querySelectorAll('.box');
console.log(boxes.length); // 5
var specialBoxes = document.querySelectorAll('#main .box.special');
console.log(specialBoxes.length); // 2
var pInspecialBox = specialBoxes[0].querySelectorAll('p');
console.log(pInspecialBox[0].innerHTML); // special p
</script>
</body>
</html>
设置元素属性的方法
setAttribute() 是 JavaScript 中用于设置元素属性的方法。它接受两个参数,第一个参数是要设置的属性名称,第二个参数是要设置的属性值。下面是该方法的详细使用说明:
语法
element.setAttribute(name, value);
参数
- name: 要设置的属性名称,必须是一个字符串。如果该属性不存在,则会创建一个新的属性,并将其添加到元素中。
- value: 要设置的属性值,可以是任何字符串。如果该属性已经存在,则会将其值设置为提供的值。如果该属性不存在,则会创建一个新的属性,并将其值设置为提供的值。
示例
假设您有一个 <img> 元素,其 src 属性为空。要将 src 属性设置为 "image.jpg",可以使用以下代码:
var img = document.querySelector("img");
img.setAttribute("src", "image.jpg");
这将把 <img> 元素的 src 属性设置为 "image.jpg"。如果该属性已经存在,则该方法将更新其值。如果该属性不存在,则该方法将创建一个新的属性,并将其添加到元素中。
注意事项
- 如果要将属性值设置为 null 或 undefined,则会将属性值设置为空字符串。
- 如果要将属性值设置为对象或函数,则会将其自动转换为字符串。
- 有些属性不能使用 setAttribute() 方法来设置,例如 style 属性和事件处理程序属性,这些属性需要使用特殊的语法来设置,后边会单独讲解。
下面列举介绍一些常见的属性:
- class 属性
class 属性用于设置元素的 CSS 类。例如,要将一个元素的类设置为 "my-class",可以使用以下代码:
element.setAttribute("class", "my-class");这将会给元素添加一个名为 "my-class" 的 CSS 类。如果元素之前已经有其他的 CSS 类,这个类将被添加到它们的后面,多个类名之间使用空格分隔。 - id 属性
id 属性用于设置元素的 ID。例如,要将一个元素的 ID 设置为 "my-element",可以使用以下代码:
element.setAttribute("id", "my-element");这将会将元素的 ID 设置为 "my-element"。一个 HTML 文档中只能有一个 ID 为 "my-element" 的元素,如果已经有了一个这样的元素,那么这个方法将会替换它的 ID。 - src 属性
src 属性用于设置图片或其他媒体文件的 URL。例如,要将一个图片元素的 src 属性设置为 "image.jpg",可以使用以下代码:
element.setAttribute("src", "image.jpg");这将会设置图片元素的 src 属性为 "image.jpg"。如果这个元素之前已经有了一个 src 属性,这个方法将会替换它的值。 -
- href 属性
href 属性用于设置链接的 URL。例如,要将一个链接元素的 href 属性设置为"www.example.com",可以使用以下代码:
element.setAttribute("href", "https://www.example.com");这将会设置链接元素的 href 属性为 "错误!超链接引用无效。 href 属性,这个方法将会替换它的值。
- href 属性
href 属性用于设置链接的 URL。例如,要将一个链接元素的 href 属性设置为"www.example.com",可以使用以下代码:
-
- alt 属性
alt 属性用于设置图片元素的替代文本。例如,要将一个图片元素的 alt 属性设置为 "My image",可以使用以下代码:
element.setAttribute("alt", "My image");这将会设置图片元素的 alt 属性为 "My image"。如果这个元素之前已经有了一个 alt 属性,这个方法将会替换它的值。
- alt 属性
alt 属性用于设置图片元素的替代文本。例如,要将一个图片元素的 alt 属性设置为 "My image",可以使用以下代码:
元素内容的设置和获取
在 JavaScript 中,textContent 、innerText、innerHTML 、和 outerHTML 都是用于获取或设置元素内容的属性,但它们之间有一些区别:
- textContent: 返回元素中包含的所有文本内容,包括隐藏文本,换行符等,但不包括 HTML 标签。它只会返回文本内容,不会包含任何 HTML 代码。
- innerText: 返回元素中包含的文本内容,并去除 HTML 标签。它只会返回可见文本,而不会包含任何隐藏文本。innerText 属性在 IE 中被首先引入,然后被其他浏览器实现。
- innerHTML: 返回元素中包含的 HTML 代码,包括标签和文本。与 innerText 不同,它会将元素的所有内容返回,包括隐藏文本和标签。
- outerHTML: 是在 innerHTML 的基础上再加上元素本身的 HTML 标签。 看以下例子:
<!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>
<style>
div {
border: 1px solid #000;
padding: 10px;
}
</style>
</head>
<body>
<div id="myDiv">
<h1>Hello World!</h1>
<p style="display: none;">This is hidden text.</p>
</div>
<script>
var myElement = document.getElementById('myDiv');
console.log('textContent:', myElement.textContent);
console.log('innerText:', myElement.innerText);
console.log('innerHTML:', myElement.innerHTML);
console.log('outerHTML:', myElement.outerHTML);
</script>
</body>
</html>
在浏览器调试窗口的输出如下:
同时也可以给 textContent 、innerText、innerHTML 、和 outerHTML 属性就行赋值操作,设置元素的内容。 看以下例子:
<!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>
<style>
div {
border: 1px solid #000;
padding: 10px;
}
</style>
</head>
<body>
<p>textContent</p>
<div id="textContent"></div>
<p>innerText</p>
<div id="innerText"></div>
<p>innerHTML</p>
<div id="innerHTML"></div>
<p>outerHTML</p>
<div id="outerHTML"></div>
<script>
var textContentDom = document.getElementById('textContent');
textContentDom.textContent = `<h1>Hello World!</h1>
<p style="display: none;">This is
hidden text.</p>`;
var innerTextDom = document.getElementById('innerText');
innerTextDom.innerText = `<h1>Hello World!</h1>
<p style="display: none;">This is
hidden text.</p>`;
var innerHTMLDom = document.getElementById('innerHTML');
innerHTMLDom.innerHTML = `<h1>Hello World!</h1>
<p style="display: none;">This is
hidden text.</p>`;
var outerHTMLDom = document.getElementById('outerHTML');
outerHTMLDom.outerHTML = `<h1>Hello World!</h1>
<p style="display: none;">This is
hidden text.</p>`;
</script>
</body>
</html>
页面上得到的结果如下:
可以看到,设置时的区别:
- textContent: 设置时不会解析 HTML 标签和特殊的字符,例如换行符。
- innerText: 设置时也不会解析 HTML 标签但是解析了换行符,文本原封不动的展示。
- innerHTML: 设置时,浏览器会解析其中的 HTML 代码并创建对应的 DOM 节点。
- outerHTML: 设置时,浏览器会解析其中的 HTML 代码并创建对应的 DOM 节点。与 innerHTML 不同的是,outerHTML 设置的内容替换了元素本身的标签。 需要注意 innerHTML 和 outerHTML 都会让浏览器进行解析,存在安全风险,因此应该避免将未经过滤和验证的用户输入作为 HTML 插入到页面中。
修改元素 class
修改元素 class 的方法
1 直接使用上面讲过的 setAttribute 方法
element.setAttribute('class', 'classValue');
2 设置 className 的属性
element.className = 'classValue';
3 使用 classList 属性
element.classList 属性是一个 DOMTokenList 对象,它提供了一组方法来添加、删除和切换元素的类。这些方法包括:
- add(className): 添加一个类到元素的类列表中
- remove(className): 从元素的类列表中删除一个类
- toggle(className): 如果元素的类列表中存在指定的类,则删除它;否则添加它
- contains(className): 检查元素的类列表中是否包含指定的类 示例代码:
let element = document.getElementById("myElement");
element.classList.add("myClass");
element.classList.remove("myClass");
element.classList.toggle("myClass");
console.log(element.classList.contains("myClass"));
通过例子可以看出来,直接设置 class 属性和使用 className 属性是相同的,都是直接操作整个 class 的取值,而当一个元素有多个 class 值共同存在的时候 classList 则功能更强大,帮我们封装好了一些方法。
修改元素 style 的方法
在 JavaScript 中,可以通过以下方法修改元素的 style 属性:
- 使用
element.style.property = value形式来设置单个 CSS 属性的值。其中,element 是元素节点,property 是 CSS 属性名称(驼峰式命名),value 是 CSS 属性的值。例如:
// 获取一个 id 为“myDiv”的元素节点
var myDiv = document.getElementById("myDiv");
// 设置元素节点的背景颜色为红色
myDiv.style.backgroundColor = "red";
// 设置元素节点的字体大小为 16 像素
myDiv.style.fontSize = "16px";
- 使用
element.setAttribute("style", "property: value; property: value; ...")的方式来设置多个 CSS 属性的值。其中,element 是元素节点,property 是 CSS 属性名称,value 是 CSS 属性的值。多个 CSS 属性之间使用分号进行分隔。例如:
// 获取一个 id 为“myDiv”的元素节点
var myDiv = document.getElementById("myDiv");
// 设置元素节点的背景颜色和字体大小
myDiv.setAttribute("style", "background-color: red; font-size: 16px;");
需要注意的是,这种方式会覆盖元素的所有样式属性,因此如果只想修改元素的某个样式属性,最好使用方法 1。此外,由于使用 setAttribute() 方法设置的 style 属性值是一个字符串,因此在修改时需要谨慎处理,以避免破坏原有的样式。
操作元素
创建元素
createElement(tagName)
创建一个指定标签名的新元素节点。
const div = document.createElement('div');
createTextNode(text)
创建一个包含指定文本内容的新文本节点。
const textNode = document.createTextNode('Hello World!');
createDocumentFragment()
createDocumentFragment()方法可以用来创建一个空的文档片段节点。文档片段节点是一种特殊类型的节点,它可以包含其他节点,但是它本身并不在文档树中占有位置,因此创建文档片段节点可以提高 DOM 操作的性能,特别是需要频繁操作 DOM 时。
下面是一个使用 createDocumentFragment()方法的示例代码,它创建了一个包含多个子节点的文档片段,并将该文档片段插入到文档树中:
// 创建一个文档片段
var fragment = document.createDocumentFragment();
// 创建多个子节点
var p1 = document.createElement("p");
p1.textContent = "这是第一个段落。";
fragment.appendChild(p1);
var p2 = document.createElement("p");
p2.textContent = "这是第二个段落。";
fragment.appendChild(p2);
var img = document.createElement("img");
img.src = "example.png";
fragment.appendChild(img);
// 将文档片段插入到文档树中
var container = document.getElementById("container");
container.appendChild(fragment);
在这个示例中,首先使用 createDocumentFragment()方法创建了一个空的文档片段节点,然后使用 createElement()方法创建了多个子节点,并使用 appendChild()方法将它们添加到文档片段中。最后,使用 appendChild()方法将文档片段节点插入到文档树中的容器元素中。这个示例演示了如何使用文档片段节点来批量添加节点,从而提高 DOM 操作的性能。
插入元素
appendChild(child)
将一个子元素节点添加到父元素节点的末尾。
const parent = document.querySelector('#parent');
const child = document.createElement('div');
parent.appendChild(child);
insertBefore(newNode, refNode)
将一个新元素节点插入到参考元素节点的前面。
const parent = document.querySelector('#parent');
const newChild = document.createElement('div');
const refChild = document.querySelector('.ref');
parent.insertBefore(newChild, refChild);
删除元素
removeChild(child)
从父元素节点中移除一个子元素节点。
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
parent.removeChild(child);
注意:在删除元素节点之前,需要先获取到它的父元素节点。
替换元素
replaceChild 和 cloneNode 是 JavaScript 中用于操作 DOM 树的方法。 replaceChild 方法用于替换父元素中的子元素。它需要两个参数:新的子元素和要被替换的旧的子元素。例如:
var parent = document.getElementById("parent");
var newChild = document.createElement("p");
var oldChild = document.getElementById("old-child");
parent.replaceChild(newChild, oldChild);
这将用新的<p>元素替换旧的子元素。
克隆元素
cloneNode 方法用于克隆元素。它接受一个布尔值参数,表示是否要克隆元素的子元素。例如:
var original = document.getElementById("original");
var clone = original.cloneNode(true);
这将克隆 original 元素及其所有子元素,并将其存储在 clone 变量中。需要注意的是,cloneNode 方法只复制元素的属性和节点值,而不会复制事件监听器或附加到元素上的任何数据。如果需要复制事件监听器或其他数据,需要手动添加到克隆的元素上。 下面再举一个设置克隆子元素和不克隆子元素的例子:
<!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="original">
<p>这是一个段落。</p>
<ul>
<li>列表项1</li>
<li>列表项2</li>
<li>列表项3</li>
</ul>
</div>
<script>
// 获取原始元素
var original = document.getElementById("original");
// 克隆元素
var deepClone = original.cloneNode(true);
// 修改克隆元素的属性
deepClone.id = "deepClone";
deepClone.getElementsByTagName("p")[0].innerHTML = "这是一个克隆的段落。";
// 将克隆元素添加到文档中
document.body.appendChild(deepClone);
// 克隆元素
var shallowClone = original.cloneNode();
// 修改克隆元素的属性
shallowClone.id = "shallowClone";
shallowClone.textContent = shallowClone.getElementsByTagName("p").length;
document.body.appendChild(shallowClone);
</script>
</body>
</html>
页面上的展现截图如下:
可以看到当不克隆子元素时,会只克隆元素本身。