小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
今天我们来复习DOM中的获取父元素、子元素和兄弟元素的API,它们主要有parentNode
、firstChild
、firstElementChild
、lastChild
、lastElementChild
、childNodes
、children
、nextElementSibling
、nextSibling
、previousElementSibling
、previousSibling
等。
目录
-
获取父元素 -
parentNode
-
获取子元素 -
firstChild
、firstElementChild
、lastChild
、lastElementChild
、childNodes
、children
-
获取兄弟元素 -
nextElementSibling
、nextSibling
、previousElementSibling
、previousSibling
获取父元素
parentNode 属性
获取DOM树中指定节点的父节点,我们可以使用parentNode
属性
let parent = node.parentNode;
parentNode
为只读属性
Document
和 DocumentFragment
没有父节点,所以 parentNode
属性将会为 null
。
parentNode 例子
下面是一个简单的页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript parentNode</title>
</head>
<body>
<div id="main">
<p class="note">这是一个段落</p>
</div>
<script>
let note = document.querySelector('.note');
console.log(note.parentNode);
</script>
</body>
</html>
控制台打印结果
如果没有指定的元素没有父元素 parentNode
属性也会为 null
。
获取子元素
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Child Elements</title>
</head>
<body>
<ul id="menu">
<li class="first">首页</li>
<li>产品</li>
<li class="current">新闻</li>
<li>博客</li>
<li>投资者</li>
<li>文档</li>
<li class="last">关于我们</li>
</ul>
</body>
</html>
firstChild
获取指定元素的第一个子节点,使用 firstChild
属性
let firstChild = parentElement.firstChild;
如果父元素没有任何子元素,则firstChild
返回null。firstChild
属性返回一个子节点,它可以是任何节点类型,例如元素节点、文本节点或注释节点。
let content = document.getElementById('menu');
let firstChild = content.firstChild.nodeName;
console.log(firstChild);
// 输出:
// #text
上面的代码输出#text
,而不是li
节点,这是因为ul
和li
之间有一段空白。
在HTML中任何空格(单个空格、多个空格、回车符和制表符)都将创建一个 #text
节点。 要删除 #text
节点,可以删除空格,如下所示
<ul id="menu"><li class="first">首页</li><li>产品</li></ul>
如果我要获取第一个元素类型的子节点,我们可以使用firstElementChild
属性
let firstElementChild = parentElement.firstElementChild;
下面代码将输出第一个li
元素
let content = document.getElementById('menu');
console.log(content.firstElementChild);
// 输出:
// <li class="first">首页</li>
lastChild
同理要获取节点的最后一个子节点,我们使用 lastChild
属性
let lastChild = parentElement.lastChild;
和firstChild
一样,如果想获取最后一个子元素,使用lastElementChild
属性
let lastChild = parentElement.lastElementChild;
下面代码将会返回ui
最后一个li
元素
let menu = document.getElementById('menu');
console.log(menu.lastElementChild);
// 输出:
// <li class="last">关于我们</li>
childNodes
获取指定元素的子元素NodeList
,使用childNodes
属性
let children = parentElement.childNodes;
和firstChild
,lastChild
相似
childNodes
属性返回具有任何节点类型的所有子元素。 要仅获取元素节点类型的子元素,请使用 children
属性:
let children = parentElement.children;
下面代码将获取ul下的所有子元素
let menu = document.getElementById('menu');
let children = menu.children;
console.log(children);
输出如下图
兄弟元素
如何获取一个元素的下一个兄弟元素、前一个兄弟元素和所有兄弟元素,假如我们的HTML结构如下
<ul id="menu">
<li>首页</li>
<li>产品</li>
<li class="current">新闻</li>
<li>博客</li>
<li>投资者</li>
<li>文档</li>
<li>关于我们</li>
</ul>
下一个兄弟元素
要获取下一个兄弟元素,使用 nextElementSibling
属性
let nextSibling = currentNode.nextElementSibling;
如果指定元素是父级下的最后一个元素,那么nextElementSibling
返回 null
。
let current = document.querySelector('.current');
let nextSibling = current.nextElementSibling;
console.log(nextSibling);
// 输出:
// <li>博客</li>
获取指定元素的所有下一个相邻的兄弟元素,我们可以加个while
循环
let current = document.querySelector('.current');
let nextSibling = current.nextElementSibling;
while(nextSibling) {
console.log(nextSibling);
nextSibling = nextSibling.nextElementSibling;
}
上一个兄弟元素
同理,获取上一个兄弟元素,使用 previousElementSibling
属性
let current = document.querySelector('.current');
let prevSibling = currentNode.previousElementSibling;
如果指定元素是父级下的第一个元素,那么previousElementSibling
返回 null
。
let current = document.querySelector('.current');
let prevSiblings = current.previousElementSibling;
console.log(prevSiblings);
// 输出:
// <li>产品</li>
同理,获取指定元素的所有上一个相邻的兄弟元素,我们可以加个while
循环
let current = document.querySelector('.current');
let prevSibling = current.previousElementSibling;
while(prevSibling) {
console.log(prevSibling);
prevSibling = prevSibling.previousElementSibling;
}
获取所有兄弟元素
要获取指定元素的所有兄弟元素,我们可以按照下面逻辑
- 首先查找指定元素的父元素,如果没有返回,说明没有任何兄弟元素
- 第二获取父元素下的第一个子节点
- 第三将第一个元素添加到
siblings
数组中 - 第四选择第一个元素的下一个兄弟元素
- 最后,循环三、四步骤,直到没有下一个兄弟元素节点
let getSiblings = function (e) {
// 存储所有兄弟元素
let siblings = [];
// 如果没有父元素,返回
if(!e.parentNode) {
return siblings;
}
// 父元素的第一个子元素
let sibling = e.parentNode.firstChild;
// 循环,记录所有兄弟元素
while (sibling) {
if (sibling.nodeType === 1 && sibling !== e) {
siblings.push(sibling);
}
sibling = sibling.nextSibling;
}
return siblings;
};
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript Siblings</title>
</head>
<body>
<ul id="menu">
<li>首页</li>
<li>产品</li>
<li class="current">新闻</li>
<li>博客</li>
<li>投资者</li>
<li>文档</li>
<li>关于我们</li>
</ul>
<script>
let getSiblings = function (e) {
// 存储所有兄弟元素
let siblings = [];
// 如果没有父元素,返回
if(!e.parentNode) {
return siblings;
}
// 父元素的第一个子元素
let sibling = e.parentNode.firstChild;
// 循环,记录所有兄弟元素
while (sibling) {
if (sibling.nodeType === 1 && sibling !== e) {
siblings.push(sibling);
}
sibling = sibling.nextSibling;
}
return siblings;
};
let siblings = getSiblings(document.querySelector('.current'));
siblingText = siblings.map(e => e.innerHTML);
console.log(siblingText);
</script>
</body>
</html>
上面代码将输出:
['首页', '产品', '博客', '投资者', '文档', '关于我们']
总结
这些很基础的DOM操作API可能平时大家用的比较少,都是借助于JQuery或者Vue、React这些MVVM这些框架,但大家要明白这些技术的底层原理也是这些很基础的DOM操作,只不过把脏活累活都帮你干了。
今天就到这里,明天继续讲讲动态创建DOM元素、动态插入。
如果你想跟着我一起复习DOM知识,微信搜索【小帅的编程笔记】,每天更新