在 jQuery 的 DOM 遍历体系中,children() 是一个非常实用的方法。它的核心职责很明确:只向下遍历一层,返回匹配元素的直接子元素。与 find() 方法不同,find() 会递归搜索所有后代,而 children() 严格限定在父子关系这一层级,这在很多需要精确控制元素范围的场景下会更为合适。
为什么我会优先选择 children() 而不是 find()?
在开发中,我发现很多开发者习惯随手使用 find(),但这样做存在隐患。如果你只想给某个容器下的直接列表项添加样式,但容器里嵌套了多层子列表,find() 就会波及到内层元素,导致样式错乱。此时 children() 能严格锁定目标,避免向下穿透。这就是“用对方法”带来的代码健壮性提升。
需要特别注意的是,children() 方法不返回文本节点。如果你需要同时获取元素节点和文本节点,应该使用 contents() 方法。这一细节在操作混合内容时容易被忽略,但理解它有助于你更精确地控制 DOM。
基本语法
$(selector).children(filter)
参数 filter 是可选的,它是一个选择器表达式,用于进一步筛选直接子元素。这个选择器的写法与你传递给 $() 函数的写法一致。当你不传 filter 时,children() 会返回所有直接子元素;传入后则只返回符合过滤条件的子集。
课程知识要点
-
单层遍历:
children()只获取直接子元素,不会像find()那样深入所有后代。 -
排除文本节点:方法返回的是元素节点,文本节点不在其中。需要文本节点时请改用
contents()。 -
可选过滤:使用
filter参数可以高效缩小匹配范围,避免额外的链式过滤操作。 -
性能考量:在已知目标元素就在子级且层级固定时,优先使用
children()而非find(),可以减少不必要的遍历开销。
示例一:获取所有直接子元素
这个示例演示如何不加过滤地获取某个容器的所有直接子元素。假设我们有一个 div 容器,内部直接放置了两个 ul 列表、一个 h2 标题和一个 p 段落。点击按钮后,所有直接子元素会被突出显示,而嵌套在内部的元素不会受到影响。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>children() 基础示例 · 编程学习</title>
<style>
.main * {
display: block;
font-size: 20px;
position: relative;
border: 2px solid #333;
color: #333;
padding: 10px;
margin: 17px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function showDirectChildren() {
$(document).ready(function () {
$("div.container").children().css({
"font-size": "30px",
"color": "#1a73e8",
"border": "6px dashed #1a73e8"
});
});
}
</script>
</head>
<body class="main">
body
<div class="container">
div 容器
<ul>
第一个 ul 元素
<h2>嵌套的标题 h2</h2>
</ul>
<ul>
第二个 ul 元素
<p>嵌套的段落元素</p>
</ul>
</div>
<button onclick="showDirectChildren()">显示直接子元素</button>
</body>
</html>
在这个例子中,div 容器内的两个 ul 都会应用新的样式,而 ul 内部的 h2 和 p 因为是后代元素而非直接子元素,不会受到任何影响。这正是 children() 严格单层遍历特性的体现。
示例二:使用 filter 参数精确筛选
在项目中,容器里常有多个同级元素,你往往只需要操作其中某一个。这时 filter 参数就非常有用。下面示例里,两个 ul 都是 div 的直接子元素,我们通过类选择器 ul.first 仅对第一个 ul 进行样式修改。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>children() 过滤示例 · 编程学习</title>
<style>
.main * {
display: block;
font-size: 20px;
position: relative;
border: 2px solid #333;
color: #333;
padding: 10px;
margin: 17px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function showFilteredChild() {
$(document).ready(function () {
$("div.container").children("ul.first-list").css({
"font-size": "30px",
"color": "#d93025",
"border": "6px dashed #d93025"
});
});
}
</script>
</head>
<body class="main">
body
<div class="container">
div 容器
<ul class="first-list">
第一个 ul 元素(带类名 first-list)
<h2>嵌套标题 h2</h2>
</ul>
<ul>
第二个 ul 元素
<p>嵌套段落</p>
</ul>
</div>
<button onclick="showFilteredChild()">显示指定子元素</button>
</body>
</html>
点击按钮后,只有类名为 first-list 的 ul 元素样式发生变化。第二个 ul 虽然也是直接子元素,但因为不满足过滤条件,不会被选中。这种精确控制在的交互组件开发中——比如标签页切换、导航高亮——非常常见。
个人经验
早期我写 jQuery 时也常不假思索地使用 find(),后来在维护一个多层菜单组件时发现,菜单高亮效果总是“穿透”到子菜单。排查后才发现是 find() 的递归特性造成的。改用 children() 后问题迎刃而解。所以,我的建议是:明确知道目标元素就是直接子元素时,不要图省事用 find(),坚持用 children(),既能提升性能,也能避免意料之外的样式入侵。
如果你在筛选后还需要对结果集做进一步处理,可以结合 .filter()、.not() 等方法链式调用,让代码逻辑更加清晰。记住,jQuery 的方法链本身就是它的一大优势,用好每个方法的边界职责,能让你的 DOM 操作代码既干净又高效。