问题描述
我最近在jQuery中被分配了一个很小但很复杂的任务,鉴于以下HTML,要求非常简单:
<div>
<span id="myid2151511" class="myclass23462362">....foobar....</span>
<span id="myid2151512" class="myclass23462362">....YoLO....</span>
<span id="myid2151513" class="myclass23462362">....lalal....</span>
<span id="myid2151514" class="myclass23462362">....foobar....</span>
</div>
我需要做的是我递归地遍历div
下的所有范围,并使用特定的ID并检查范围中包含的值是否为foobar
,因此我可以使用以下jQuery代码:
$(function(){
$('div [id^="myid"]:contains("foobar"):last').css({'background' : 'rgb(227, 216, 22)' })
});
就其本身而言,这是相当复杂的代码,但是jQuery文档对我来说是一个轻而易举的事,因为对于理解代码而言。
现在,我很喜欢在jQuery中编写代码:
$('some-Element').somemethod().anothermethod().yetanothermethod();
每个函数在上面的jQuery语句中都返回一个值,因此链接能力成为现实。
但是当我看到这样的代码时。
$('div [id^="myid"]:contains("foobar"):last').css({'background' : 'rgb(227, 216, 22)' });
我有点不高兴(尽管我自己设法写了上面的行),请注意选择器:last
和:contains
是如何进行大量过滤的,对我来说,它们似乎在工作,就像某种jQuery方法。
所以我的问题是,与jQuery方法相比,jQuery中的这些选择器如何工作?
如果有人可以解释或给我一个模糊的想法,那就太好了。
编辑 ::
$(".someClass").eq('10');
一行中向我阐明我的问题$(".someClass").eq('10');
是有道理的,但是$(".someClass:eq(10)")
不起作用,我的意思是它可以工作,但是它是如何在内部实现的?(我在阅读了下面的答案后写了这个编辑,还有这个问题到现在为止已经完全回答了,但是此编辑只是为了澄清我的问题。)
1楼
dmeglio
4
2015-07-26 15:37:08
这是一个有趣的问题。 简短的答案是,他们俩都完成同一件事。 当然,故事总会有更多。 一般来说:
$('div [id^="myid"]:contains("foobar"):last').css({'background' : 'rgb(227, 216, 22)' });
等效于:
$("div").find("[id^='myid']").filter(":contains('foobar')").last().css({'background' : 'rgb(227, 216, 22)' });
在大多数情况下,当您调用$()时,jQuery会调用document.querySelectorAll()
。
这是浏览器实现的功能,可基于选择器获取元素。
您创建的复杂字符串将传递给此方法,并返回元素。
自然,浏览器实现的功能比JavaScript快,因此JavaScript越少C ++越多越好。
结果,将所有内容作为选择器传递的示例可能会更快,因为它只是将所有内容作为一个调用发送到浏览器并告诉它“执行”。
另一方面,调用$()
, contains()
, last()
将多次调用querySelectorAll
,因此它可能会比较慢,因为我们使用了更多的JavaScript,而不是让浏览器一次完成繁重的工作。
但是也有例外。
jQuery 通常调用querySelectorAll
。
但是,有时却并非如此。
这是因为jQuery扩展了querySelectorAll
的功能。
例如,如果您根据执行类似$(".someClass:eq(10)")
的操作:
jQuery使用以下选择器扩展了CSS3选择器。 由于这些选择器是jQuery扩展,而不是CSS规范的一部分,因此使用它们的查询无法利用本机DOM querySelectorAll()方法提供的性能提升。 为了在使用这些选择器时获得最佳性能,请首先使用纯CSS选择器选择一些元素,然后使用.filter()。
因此,在那种情况下,虽然$(".someClass:eq(10)")
看起来更快,但实际上$(".someClass").eq(10)
或$(".someClass").filter(":eq(10)")
将更快,因为第一个调用将作为JavaScript代码执行。
后两者将首先调用querySelectorAll
按类进行选择,然后仅使用JavaScript查找第十个元素。
当jQuery必须使用纯JavaScript进行选择时,它使用Sizzle引擎进行选择,该引擎速度非常快,但并不比浏览器中的本机代码快。
再次,简短的答案是,它们是同一回事,长答案是,这取决于。
如果您对属于该类别的所有扩展都感兴趣,那么到我包含的jQuery文档的链接会列出它们。
2楼
1
已采纳
首先,是的,尼克希尔是对的。 ID是唯一的标识符,只能使用一次。 如果您愿意将相同的样式应用于多个元素,或者要使用它来选择多个元素,请一起使用class属性。 但是,我听不懂你的问题。 但这可能会有所帮助
javascript中有功能,几乎所有主流浏览器都广泛支持该功能
document.querySelectorAll("div [id^=myId]");
实际上,您可以编写自己的库(不是像jquery那样高级的库,但是)
var $ = function(selector){
return document.querySelectorAll(selector);
}
// and then you could use it like this
var elementsWithMyId = $("div [id^=myId]");
// where elementsWithMyId will contain array of all divs which's id start with myId
因此,据我了解您的问题,不,在jQuery选择之后没有任何魔术发生,只是浏览器内置的功能而被jquery缩短了。 当然,他们添加了许多新功能,它们的工作方式如下:
var $ = function(selector){
var elementsArray = document.querySelectorAll(selector);
elementsArray.makeBlue = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "blue";
}
// so elementsArray will now have function to make all of its
// div blues. but if you want to have chain like that, we have to return this array not just make all of it blue
return elementsArray;
}
elementsArray.makeRed = function(){
for(var i = 0; i < elementsArray.length; i++){
elementsArray[i].style.backgroundColor = "red";
}
return elementsArray;
}
return elementsArray;
}
// so now you can use it like this
// this returns array which has options make blue, and make red so lets use make blue first
// makeBlue then returns itself, meaning it returns array which has again options of making itself red and blue so we can use makeRed now
$("div [id^=myId]").makeBlue().makeRed();
就是这样!