【问题标题】:What is "context" in jQuery selector?jQuery 选择器中的“上下文”是什么?
【发布时间】:2013-05-01 14:37:26
【问题描述】:

有什么区别

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

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

?

【问题讨论】:

  • 没有区别。 “上下文”的事情导致 jQuery 在内部执行 $(context).find(selector)
  • @Pointy,你错了:-p
  • 当您更改选择器时,答案也发生了变化,因此我发布了与最新版本相关的内容。
  • @LightnessRacesinOrbit - 这与目前的问题不同。
  • @zzzzBov ??我想我应该明确指出张贴的两个特定声明会做同样的事情。

标签: javascript jquery jquery-selectors


【解决方案1】:

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

编辑:外行人的每个例子:

  • 打电话给镇上所有的蓝色房子(上下文),如果简在那里,请揭发她的帽子。
  • 呼叫镇上的所有建筑物(还没有上下文)。如果它是一座蓝色的房子(添加上下文)并且 Jane 在那里,请揭发她的帽子。

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

首先我们有:上下文选择器 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);

这符合上下文选择器的要求:“A DOM Element, Document, or jQuery to use as context”。

这就是说:使用上下文,在里面找到选择器。等价物是:

$('#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/,它表示:找到 #storePreferences 元素内的所有 input.current_title 元素。这就是棘手的地方! - 这正是它的作用 -

找到所有input.current_title(任何地方),然后找到#storePreferences元素内的那些

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

因此形式为:

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

很可能会比后代版本表现更好。

【讨论】:

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

$('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');

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

它们不同的原因是使用find 允许在调用end 时将上下文返回到#storePreferences

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 );
}

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

【讨论】:

  • 您能否提供一个简单的案例示例,说明此语法的效果会有所不同?
  • 这不是这个问题的全部答案,尽管他改变了确实改变了问题的选择器——在这种情况下很明显。
  • @MarkSchultheiss,对选择器的更改是微不足道的。性能不是也不应该成为讨论的一部分,因为它确实是过早的优化。 JavaScript 中有太多的异步行为,以至于性能很少是值得关注的问题。
  • 但在这种情况下,性能是差异的重要组成部分,与优化无关,但与 jQuery 内部发生的事情有关,即“有区别” - 以及变化在我看来,通过 id 和 class 查找元素并非易事。
【解决方案3】:

在你的例子中,我相信差别不大。

当您开始在特定 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 var sp = $('body div#storePreferences'); 的 id 获取正文中的 div” 这不是严格正确的,恕我直言,这是一个错误的选择器,有一个 ID,它应该总是被使用,并且只能使用最快的,尤其是在旧的浏览器中。根据规范,ID 在文档中必须是唯一的。您的选择器真正做的是 1. 按 ID 选择 #storePreference 元素。然后在div 中找到所有那些#storePreference 元素,然后在body 中找到它
  • 这是由于选择器从右到左的使用和在使用中的 Sizzle 引擎中的进展。遍历所有 div 元素,然后通过 ID 获得元素后的正文不仅效率低下,而且恕我直言,比简单的 var sp = $('#storePreference'); 更令人困惑
  • 最快,给定你最后一个例子$('#storePreferences input.current_title').prop('disabled', false);实际上是使用$('#storePreferences').find('input.current_title').prop('disabled', false);
  • 注意,您是正确的,因此$('#storePreferences input.current_title').prop('disabled', false); 比上面基于上下文的选择要慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多