在开发中,我经常遇到需要知道某个元素在它兄弟节点中排第几的情况。比如做一个选项卡组件,点击某个标签页时需要知道它是第几个,好去展示对应的内容面板;或者做一个列表,用户点击某项时要把它的序号传给后端。index() 方法就是专门用来获取这个位置信息的。
它的返回值很简单:一个从0开始计数的整数,代表元素在某个参考系中的位置。如果元素不存在于参考范围中,返回 -1。
三种调用方式与不同含义
index() 方法根据传入参数的不同,计算位置的参照物也不同。这一点是初学者容易混淆的地方,需要分开讲清楚。
方式一:不传任何参数
$(selector).index()
这种写法返回的是jQuery对象中第一个匹配元素在其同级兄弟节点中的位置索引。参照物是它的所有兄弟元素,不论兄弟是什么标签类型。
方式二:传入一个DOM元素或jQuery对象
$(selector).index(element)
这种写法返回的是传入的 element 在 $(selector) 这个中的位置。注意参照物变了——不再是兄弟节点,而是 $(selector) 选出来的那一组元素。
方式三:传入一个选择器字符串
$(selector).index("selectorString")
这种写法返回的是jQuery对象中第一个匹配元素在由选择器字符串匹配到的元素中的位置。可以理解为:先拿 "selectorString" 找出一个参照元素,再看当前元素在这个参照里排第几。
为什么 .index() 比手动遍历省心
在没有 index() 方法的年代,想获取一个元素在兄弟中的位置,得写一个循环去遍历父元素的 children 节点,逐一比对。代码啰嗦不说,还容易把文本节点、注释节点也算进去,导致计数偏差。
index() 把这些脏活封装起来了,而且它对不同类型的节点做了正确的过滤,只关注元素节点。这是我的一个切身体会——早年用原生JavaScript写标签页切换时,经常因为换行产生的文本节点让索引对不上,换成 index() 后就没再踩过这个坑。
实战示例:点击列表项显示三种索引值
这个例子用一个物品清单来演示 index() 三种用法的差异。每个列表项点击后会同时展示三种索引,方便直观对比。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jQuery index() 三种用法对比</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$(".item").click(function() {
// 清除上一次的高亮
$(".item").css({"background-color": "#fff", "border": "1px solid #ddd"});
// 高亮当前点击的项
$(this).css({"background-color": "#fff3cd", "border": "2px solid #ffc107"});
// 方式一:不传参,返回当前元素在兄弟节点中的索引
var idxSiblings = $(this).index();
// 方式二:传选择器字符串 .item,返回在同类元素中的索引
var idxItemClass = $(this).index(".item");
// 方式三:传ID选择器 #second,返回在以该ID为参照的中的索引
var idxById = $(this).index("#second");
// 显示三种索引结果
$("#result-siblings").text(idxSiblings);
$("#result-item").text(idxItemClass);
$("#result-id").text(idxById);
});
});
</script>
<style>
.item {
padding: 10px 15px;
margin: 4px 0;
border: 1px solid #ddd;
cursor: pointer;
border-radius: 4px;
list-style: none;
}
.result-panel {
margin-top: 15px;
padding: 12px;
border: 2px solid #333;
background-color: #f5f5f5;
line-height: 1.8;
}
</style>
</head>
<body>
<h3>jQuery index() 方法——三种索引对比</h3>
<p>依次点击下方各项,观察三种索引值的不同。</p>
<ul style="padding: 0;">
<li class="item">苹果</li>
<li class="item" id="second">香蕉(带 id="second")</li>
<li class="item">橙子</li>
<li class="item">葡萄</li>
<li class="item">西瓜</li>
</ul>
<div class="result-panel">
<strong>使用 .index()(无参数,相对于兄弟节点):</strong>
<span id="result-siblings">-</span><br>
<strong>使用 .index(".item")(相对于同类选择器):</strong>
<span id="result-item">-</span><br>
<strong>使用 .index("#second")(相对于id为second的元素):</strong>
<span id="result-id">-</span>
</div>
</body>
</html>
在这个示例中,三种索引的差异体现得很明显:
-
无参数的
.index()统计的是当前点击元素在所有兄弟<li>中的位置,点击"苹果"返回0,"香蕉"返回1,依此类推。 -
.index(".item")的参照是$(".item")选出的五个元素,因为所有列表项都有item这个类名,所以结果和无参数版本一致。 -
.index("#second")比较特殊——它的参照是$("#second")选出的元素,这个里只有香蕉自己。如果点击香蕉,它在$("#second")这个单元素里的索引是0;但点击其他项时,它们在$("#second")中不存在,返回值是-1。
这个 -1 在项目里可以用来做条件判断。比如判断某个元素是否属于某个特定,比起用 length 判断,有时候用 index() 可读性更高。
本节课程知识要点
-
index()方法用于获取元素在指定参照系中的索引位置,索引从0开始计数,元素不存在时返回 -1。 -
不传参数时,
$(selector).index()返回的是jQuery对象第一个匹配元素在其同级兄弟节点中的位置,参照物是所有兄弟元素节点。 -
传入一个DOM元素或jQuery对象时,
$(selector).index(element)返回的是传入元素在$(selector)中的位置。 -
传入选择器字符串时,
$(selector).index("selector")返回的是当前元素在由该选择器匹配到的元素中的位置,这个参照独立于原始兄弟关系。 -
index()只统计元素节点,自动忽略文本节点和注释节点,避免了手动遍历childNodes时容易出现的计数偏差问题。