jQuery 选择器中的“上下文”是什么?

IT技术 javascript jquery jquery-selectors
2021-01-22 19:56:47

有什么区别吗

$('input.current_title', '#storePreferences').prop('disabled', false);

$('#storePreferences input.current_title').prop('disabled', false);

?

3个回答

有区别,它并不像其他人认为的那样微妙。

编辑:外行的例子:

  • 打电话给镇上所有的蓝房子(上下文),如果简在那里,请给她小费。
  • 呼叫镇上的所有建筑物(尚无上下文)。如果它是一个蓝色的房子(添加上下文)并且简在那里,请揭开她的帽子。

让我们分解一下它选择的内容。

首先我们有:上下文选择器 http://api.jquery.com/jQuery/#jQuery-selector-context

$('input.current_title', '#storePreferences').prop('disabled', false);

这表示:在上下文中使用选择器。 http://api.jquery.com/jQuery/#jQuery-selector-context

虽然这种形式可能有效,但它真的应该是:

$('input.current_title', $('#storePreferences')).prop('disabled', false);

或者

var myContext = $('#storePreferences');
$('input.current_title', myContext).prop('disabled', false);

这满足了满足上下文选择器的要求:“用作上下文的 DOM 元素、文档或 jQuery”。

这说:使用上下文,在里面找到选择器。一个等价的将是:

$('#storePreferences').find('input.current_title').prop('disabled', false);

这就是内部发生的事情。查找'#storePreferences'并在其中找到所有'input.current_title'匹配的元素。


然后我们有:后代选择器

$('#storePreferences input.current_title').prop('disabled', false);

这是一个后代选择器(“祖先后代”)http://api.jquery.com/descendant-selector/它说:找到input.current_title元素内的所有#storePreferences元素。这就是棘手的地方!- 这正是它的作用 -

找到 ALL the input.current_title(anywhere),然后找到那些 INSIDE the #storePreferenceselement

因此,我们遇到了 jQuery 的 Sizzle 从右到左选择器 - 所以它最初发现(可能)比它需要的更多,这可能是一个性能问题/问题。

因此形式为:

$('#storePreferences').find('input.current_title').prop('disabled', false);

最有可能比 Descendant 版本表现更好。

好吧,现在 JQuery 几乎不可能改变它的实现并破坏将选择器字符串作为第二个参数传递的代码。因此,在实践中,以这种方式使用它可能没有什么害处,除非您没有按照应有的方式遵守文档并且感觉是错误的
2021-03-12 19:56:47
@zzzzBov - 关于文档可能是正确的,但严格来说,这是我们在这个时刻必须经历的事情,因此我以我的方式解决了这个问题。
2021-03-21 19:56:47
实施总是胜过文档。
2021-03-21 19:56:47
我更喜欢编写文档并报告实现错误——如果它们被证明文档错误那么好,但如果文档是从设计中构建的,并且产品是用 TDD 构建的,那么理论上事情应该匹配。接口编码很好
2021-03-29 19:56:47
当第二个参数 tojQuery是一个字符串时,它执行上下文查找,所以我猜想只是文档中的一个错误需要解决。
2021-04-04 19:56:47

有什么区别$('input.current_title', '#storePreferences').prop('disabled', false);$('#storePreferences input.current_title').prop('disabled', false);

是的,但它很微妙

不同之处在于如何选择元素。

$('input.current_title', '#storePreferences');

相当于1

$('#storePreferences').find('input.current_title');

等同于:

$('#storePreferences input.current_title');

即使相同的元素会受到影响。

它们不同的原因是 usingfind允许#storePreferencesend调用返回上下文

1:jQuery v1.9.1 源代码中的第 194-202 行
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
    return ( context || rootjQuery ).find( selector );

// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
    return this.constructor( context ).find( selector );
}

在您的问题的上下文中,将修改相同的元素,因此功能上没有区别,但重要的是要了解您使用的选择器的更广泛含义。

但是在这种情况下,性能是差异的重要组成部分,与优化无关,但与 jQuery 内部发生的事情有关,即“是否存在差异” - 以及通过 id 和 by 查找元素的变化在我看来,课堂并非微不足道。
2021-03-13 19:56:47
这不是这个问题的完整答案,尽管他更改了确实改变问题的选择器 - 在这种情况下非常重要。
2021-03-15 19:56:47
@MarkSchultheiss,对选择器的更改微不足道。性能不是也不应该成为讨论的一部分,因为它确实是过早的优化。JavaScript 中有如此多的异步行为,以至于性能很少成为值得关注的问题。
2021-03-24 19:56:47
您能否提供一个简单的案例示例,请说明此语法的效果不同?
2021-04-08 19:56:47

在您的示例中,我认为几乎没有区别。

当您开始选择特定 DOM 元素中的多个元素时,它会得到更好的使用。

// Get the div in the body with the id of storePreferences
var sp = $('body div#storePreferences');


// jQquery will only look for **input.current_title** **input.name** **input.age** in side **sp** div in the DOM.
// Faster
$('input.current_title', sp).prop('disabled', false);
$('input.name', sp).prop('disabled', false);
$('input.age', sp).prop('disabled', false);




// jQquery will look for **input.current_title** in entire DOM
// Slower
$('#storePreferences input.current_title').prop('disabled', false);
最快的,鉴于你的最后一个例子$('#storePreferences input.current_title').prop('disabled', false);实际上是使用$('#storePreferences').find('input.current_title').prop('disabled', false);
2021-03-24 19:56:47
这是由于在使用中的 Sizzle 引擎中选择器的使用和进展是从右到左的。遍历所有 div 元素,然后在你已经通过 ID 拥有一个元素之后的 body 不仅效率低下,而且恕我直言,比简单地更令人困惑var sp = $('#storePreference');
2021-04-02 19:56:47
因为这确实是关于您的评论的问题:“// Get the div in the body with the id of storePreferences var sp = $('body div#storePreferences');” 这不是严格正确的,恕我直言是一个糟糕的选择器,有一个 ID,它应该总是被使用,并且只有使用速度最快,尤其是在较旧的浏览器中。每个规范的文档中的 ID 必须是唯一的。您的选择器真正做的是 1.#storePreference按 ID选择元素。THEN#storePreference在 a 中找到所有这些元素div,然后在body
2021-04-09 19:56:47
请注意,您是正确的,因此它$('#storePreferences input.current_title').prop('disabled', false);比上面的基于上下文的选择慢。
2021-04-09 19:56:47