gpt4 book ai didi

jquery - 使用 :first 时 Children() 和 find() 的行为

转载 作者:行者123 更新时间:2023-12-03 22:22:58 24 4
gpt4 key购买 nike

我对使用 children() 时的行为有点困惑和find():first .

考虑以下标记:

<div class="parent">
<div>1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>

<div class="parent">
<div>1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>

据我了解,以下内容应该返回相同的元素集合,因为没有孙子(这是 find()documentationchildren() 之间所述的唯一区别)。

但是,如果我向第一个 .child 添加一个类,结果不同:

$('.parent').find('.child:first').addClass('active');

产生以下标记:

<div class="parent">
<div>1</div>
<div class="child active">2</div>
<div class="child">3</div>
</div>

<div class="parent">
<div>1</div>
<div class="child active">2</div>
<div class="child">3</div>
</div>

当使用children()做同样的事情时方法,我得到:

<div class="parent">
<div>1</div>
<div class="child active">2</div>
<div class="child">3</div>
</div>

<div class="parent">
<div>1</div>
<div class="child">2</div>
<div class="child">3</div>
</div>

为什么?

Here's a fiddle

最佳答案

问得好!

TL;DR

不同之处在于,find 从每个包装元素开始单独搜索,然后聚合结果,而 children 获取候选结果的单个聚合池,然后根据这些结果进行过滤在指定的选择器上。如果原始 jQuery 对象包装多个元素,这会导致像 :first 这样的选择器给出不同的结果。

这样做的原因是可以理解的(children 从一开始就知道所有可能的匹配在 DOM 中共享一个非常重要的属性,因此缩小候选列表的范围是有意义的出于性能原因放在前面),但在我看来,除了当前实现中的错误之外,您不能将结果称为任何其他内容。

$.fn.find

find 会产生两个这样的匹配,因为它对当前 jQuery 对象的每个包装元素运行搜索,然后聚合结果。因此,对于每个 .parent,我们按照文档顺序匹配第一个后代,即 .child

来源如下:

function (selector) {
var i, ret = [],
self = this,
len = self.length;

if (typeof selector !== "string") {
return this.pushStack(jQuery(selector).filter(function () {
for (i = 0; i < len; i++) {
if (jQuery.contains(self[i], this)) {
return true;
}
}
}));
}

for (i = 0; i < len; i++) {
jQuery.find(selector, self[i], ret); // ** IMPORTANT **
}

// Needed because $( selector, context ) becomes $( context ).find(selector)
ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
ret.selector = this.selector ? this.selector + " " + selector : selector;
return ret;
}

一切都发生在标记为“重要”的行中:jQuery.findSizzle 的别名。 ,每次将其结果附加ret。显然,如果您对一个包装 N 个元素且每个元素至少有一个后代的 jQuery 对象执行 .find(":first") 操作,您将准确返回 N 个结果。

$.fn.children

children 采用另一条路线:对于每个包装元素,它遍历 DOM 以获取其子元素,然后根据选择器作为一个整体过滤结果。显然,在这种情况下,最多会留下一个元素作为最终结果。

事情是这样发生的:

function (until, selector) {
var ret = jQuery.map(this, fn, until); // ** IMPORTANT 1 **

if (name.slice(-5) !== "Until") {
selector = until;
}

if (selector && typeof selector === "string") {
ret = jQuery.filter(selector, ret); // ** IMPORTANT 2 **
}

if (this.length > 1) {
// Remove duplicates
if (!guaranteedUnique[name]) {
ret = jQuery.unique(ret);
}

// Reverse order for parents* and prev-derivatives
if (rparentsprev.test(name)) {
ret = ret.reverse();
}
}

return this.pushStack(ret);
}

这并不是不言自明的,因为代码与一堆对 DOM 进行结构遍历的方法共享(parentnextprev siblings 等),但代码的相关部分也非常简单:“IMPORTANT 1”行收集内部结构遍历(“获取子级”)的结果ret,并且这些结果作为一个整体根据选择器(“.child:first”)进行过滤。这最终最多会留下一个结果。

关于jquery - 使用 :first 时 Children() 和 find() 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25306939/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com