not() 方法是 jQuery 中用于反向筛选的一个实用工具。它的逻辑和 filter() 刚好相反:filter() 是保留匹配条件的元素,而 not() 是把匹配条件的元素从中移除,保留那些不匹配的。换句话说,not() 返回的是“除了指定条件之外”的所有元素。
这个方法同样支持两种筛选方式:传入选择器表达式或传入回调函数。选择器方式适合排除特定类名、ID 或标签的元素;回调函数则让你能基于任意复杂逻辑来决定哪些元素需要被排除。
为什么我在排除特定元素时更愿意用 not() 而不是 filter() 写成取反条件?
这是一个代码可读性的问题。假设你要从一组段落中排除带有 .featured 类的元素,用 not(".featured") 比用 filter(":not(.featured)") 或 filter(function(){ return !$(this).hasClass("featured"); }) 更直观。not() 让“排除”这一意图直接体现在方法名上,阅读代码的人不需要在脑中做一次逻辑反转,理解和维护都轻松很多。
语法
使用选择器条件:
$(selector).not(criteria)
使用回调函数:
$(selector).not(function(index) {
// 返回 true 表示将该元素从结果中移除
// 返回 false 表示保留该元素
})
参数说明:
-
criteria(可选):一个 jQuery 对象、选择器表达式,或用逗号分隔的多个选择器。匹配这些条件的元素会被从中排除。 -
function(index)(可选):为中每个元素执行的回调函数。index是当前元素在中的位置(从 0 开始)。函数返回true时该元素被移除,返回false时保留。
课程知识要点
-
与 filter() 逻辑互逆:
filter()返回匹配的元素,not()返回不匹配的元素。两者搭配使用可以灵活地拆分元素。 -
不修改原始:
not()返回一个新的 jQuery 对象,原有的元素不受影响。 -
函数参数的返回值含义:在
not()的回调中,return true代表“排除该元素”,这一点与filter()刚好相反,容易混淆,需要特别注意。 -
索引从 0 开始:回调函数中的
index参数反映元素在原中的位置,与eq()和filter()的规则一致。 -
支持多个选择器:用逗号分隔可以一次性排除多种类型或类名的元素,避免链式调用多个
not()。
示例一:使用选择器排除特定类名的元素
这个例子展示了用选择器参数从一组段落中排除带有 featured 类的元素,只给普通段落应用高亮背景。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>not() 选择器排除示例 · 编程学习</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
div {
font-size: 20px;
font-weight: bold;
margin: 5px 0;
}
</style>
<script>
function filterByNot() {
$(document).ready(function () {
// 排除类名为 featured 的 p 元素,保留其余的
$("p").not(".featured").css({
"background": "#fff3cd",
"padding": "8px"
});
});
}
</script>
</head>
<body>
<h2>编程课程目录</h2>
<h4>使用 not() 排除精华内容,只保留普通条目</h4>
<div id="div1">第一个 div 元素</div>
<p class="featured">P1:JavaScript 入门(精华)</p>
<div id="div2">第二个 div 元素</div>
<p>P2:通用编程基础</p>
<p>P3:版本控制入门</p>
<p class="featured">P4:Vue 前端框架(精华)</p>
<p>点击下方按钮,高亮非精华内容:</p>
<button onclick="filterByNot()">排除精华条目</button>
</body>
</html>
点击按钮后,P2 和 P3 背景变黄,而 P1 和 P4 因为带有 featured 类被 not() 排除在外,样式保持不变。div 元素因为选择器 $("p") 的范围限定,不在操作对象之内。
示例二:使用回调函数按索引排除
回调函数参数让你能按索引等动态条件来排除元素。下面的代码排除索引为 1 和 2 的元素(即中的第 2 和第 3 个),保留第 1 和第 4 个。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>not() 函数排除示例 · 编程学习</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
div {
font-size: 20px;
font-weight: bold;
margin: 5px 0;
}
</style>
<script>
function filterByNotFunc() {
$(document).ready(function () {
$("p").not(function (index) {
// 索引为 1 和 2 的元素返回 true,表示被排除
return index === 1 || index === 2;
}).css({
"background": "#fff3cd",
"padding": "8px"
});
});
}
</script>
</head>
<body>
<h2>编程课程目录</h2>
<h4>使用 not() 排除索引 1 和 2 的元素</h4>
<div id="div1">第一个 div 元素</div>
<p>P0:HTML 基础</p>
<div id="div2">第二个 div 元素</div>
<p>P1:CSS 布局</p>
<p>P2:JavaScript 基础</p>
<p>P3:项目实践</p>
<p>点击下方按钮查看效果:</p>
<button onclick="filterByNotFunc()">按索引排除</button>
</body>
</html>
点击后,P0 和 P3 高亮,P1 和 P2 被排除。注意这里索引从 0 起算,P0 对应索引 0,P3 对应索引 3,两个被保留的元素恰好是视觉上的第 1 和第 4 项。
个人经验与实用建议
我在项目中经常把 filter() 和 not() 成对使用。比如在一个待办列表里,已完成和未完成的任务通常共用同一个样式基类,用 filter(".done") 处理已完成项,用 not(".done") 处理未完成项,逻辑一目了然。
一个容易出错的地方是 not() 回调函数的返回值含义与 filter() 正好相反。filter() 里 return true 是保留,not() 里 return true 却是排除。在同一个函数里混用两者时,我习惯在调用 not() 的地方加一行简短注释提醒自己,避免逻辑写反。
如果你用的是较新版本的 jQuery,并且想用原生的思维方式来写排除逻辑,也可以用 filter() 配合 :not() 伪类选择器来达成相同效果。但在调试时,not() 方法名自身就是一份清晰的意图声明,让代码意图更容易被他人读懂。对于团队协作来说,这种可读性上的收益在长期维护中很有价值。