jQuery 提供了一个名为 $.each() 的对象迭代器工具,以及一个 jQuery 集合迭代器:.each()。这两者是不可互换的。此外,还有两个非常有用的方法 $.map() 和 .map(),它们可以简化我们常见的某些迭代使用场景。
链接 $.each()
$.each() 是一个通用的迭代器函数,用于循环遍历对象、数组和类数组对象。普通对象通过其命名属性进行迭代,而数组和类数组对象则通过其索引进行迭代。
$.each() 基本上是传统 for 或 for-in 循环的直接替代方案。假设有:
|
1
2
3
|
|
那么这段代码:
|
1
2
3
4
5
|
|
可以替换为:
|
1
2
3
4
5
|
|
注意,我们不需要通过 arr[ index ] 来访问值,因为该值会被方便地传递给 $.each() 的回调函数。
此外,假设有:
|
1
2
3
4
5
|
|
那么这段代码:
|
1
2
3
4
5
|
|
可以替换为:
|
1
2
3
4
5
|
|
同样地,我们不需要直接访问 obj[ key ],因为值会直接传递给回调函数。
请注意,$.each() 适用于普通对象、数组以及非 jQuery 集合的类数组对象。
以下做法被认为是错误的:
|
1
2
3
4
|
|
对于 jQuery 集合,请使用 .each()。
链接 .each()
.each() 直接用于 jQuery 集合。它遍历集合中每个匹配的元素,并对该对象执行回调。当前元素在集合中的索引会作为参数传递给回调。值(在本例中为 DOM 元素)也会被传递,但回调是在当前匹配元素的上下文中触发的,因此 this 关键字指向当前元素,这与 jQuery 其他回调函数的预期一致。
例如,给定以下标记:
|
1
2
3
4
5
|
|
可以像这样使用 .each():
|
1
2
3
4
5
6
7
8
|
|
链接 第二个参数
经常有人问:“如果 this 就是该元素,为什么还要向回调函数传递第二个 DOM 元素参数呢?”
无论是故意还是无意,执行上下文都可能会改变。如果一味使用 this 关键字,很容易让我们自己或其他阅读代码的开发人员感到困惑。即使执行上下文保持不变,将第二个参数作为命名参数使用可能会使代码更具可读性。例如:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
|
链接 有时 .each() 并非必要
许多 jQuery 方法都会隐式地遍历整个集合,将其行为应用于每个匹配的元素。例如,以下操作是不必要的:
|
1
2
3
|
|
而这样写就可以了:
|
1
|
|
文档中的每个 <li> 都会被添加 "newClass" 类。
另一方面,某些方法不会遍历集合。当我们需要在设置新值之前从元素中获取信息时,就需要使用 .each()。
以下写法将无法正常工作:
|
1
2
3
4
|
|
相反,应该这样写:
|
1
2
3
4
|
|
以下是需要使用 .each() 的方法列表:
.attr()(获取器).css()(获取器).data()(获取器).height()(获取器).html()(获取器).innerHeight().innerWidth().offset()(获取器).outerHeight().outerWidth().position().prop()(获取器).scrollLeft()(获取器).scrollTop()(获取器).val()(获取器).width()(获取器)
请注意,在大多数情况下,“获取器(getter)”签名返回的是 jQuery 集合中第一个元素的结果,而“设置器(setter)”则作用于整个匹配元素集合。唯一的例外是 .text(),其获取器签名将返回所有匹配元素文本内容的拼接字符串。
除了设置值之外,属性(attribute)、属性(property)、CSS 设置器和 DOM 插入“设置器”方法(即 .text() 和 .html())也接受匿名回调函数,这些函数会应用于匹配集中的每个元素。传递给回调的参数是匹配元素在集合中的索引以及该方法“获取器”签名的结果。
例如,以下两种写法是等效的:
|
1
2
3
4
5
6
7
8
|
|
关于这种隐式迭代,另一件需要记住的事情是,诸如 .children() 或 .parent() 之类的遍历方法将作用于集合中的每个匹配元素,并返回所有子节点或父节点的组合集合。
链接 .map()
有一个常见的迭代用例可以通过使用 .map() 方法得到更好的处理。每当我们想要根据 jQuery 选择器中所有匹配的元素创建一个数组或拼接字符串时,使用 .map() 会更合适。
例如,与其这样做:
|
1
2
3
4
5
|
|
我们可以这样做:
|
1
2
3
|
|
注意最后链式调用的 .get()。即使我们在回调中返回字符串,.map() 实际上返回的也是一个 jQuery 包装的集合。我们需要使用不带参数版本的 .get(),以便返回一个我们可以处理的基础 JavaScript 数组。要将其拼接成字符串,我们可以在 .get() 之后链式调用原生的 JS 数组方法 .join()。
链接 $.map
与 $.each() 和 .each() 类似,既有 $.map() 也有 .map()。它们的区别也与两种 .each() 方法非常相似。$.map() 作用于普通 JavaScript 数组,而 .map() 作用于 jQuery 元素集合。因为它作用于普通数组,所以 $.map() 返回的是普通数组,不需要调用 .get() —— 事实上,如果调用它会抛出错误,因为它不是原生的 JavaScript 方法。
特别提醒:$.map() 切换了回调参数的顺序。这样做是为了与 ECMAScript 5 中提供的原生 JavaScript .map() 方法相匹配。
例如:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
|