jQuery方法Vs jQuery选择器

jQuery methods Vs jQuery selectors

本文关键字:jQuery 选择器 方法 Vs      更新时间:2023-09-26

我最近被分配了一个非常小但复杂的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下的所有span,使用特定的id并检查span中包含的值是否为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中的选择器是如何工作的?

如果有人可以解释或给我一个模糊的想法,那将是非常棒的。

EDIT::

很好地用一行来澄清我的问题,对我来说$(".someClass").eq('10');是有意义的,但不知何故$(".someClass:eq(10)")没有,我的意思是它是有效的,但它到底是如何在内部实现的?(我在阅读了下面的答案后写了这个编辑,现在这个问题已经得到了彻底的回答,但这个编辑只是为了澄清我的问题。

这是个有趣的问题。简单地说,它们的作用是一样的。当然,故事中总是有更多的内容。总的来说:

$('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的功能。

例如,如果您按照jQuery文档执行$(".someClass:eq(10)")操作:

jQuery扩展了CSS3的选择器,包含以下选择器:因为这些选择器是jQuery扩展而不是CSS规范的一部分,所以使用它们的查询不能利用本机DOM querySelectorAll()方法提供的性能提升。为了在使用这些选择器时获得最佳性能,首先使用纯CSS选择器选择一些元素,然后使用.filter()。

所以在这种情况下,虽然$(".someClass:eq(10)")可能看起来更快,但实际上$(".someClass").eq(10)$(".someClass").filter(":eq(10)")将更快,因为第一次调用将作为JavaScript代码执行。后两者将首先调用querySelectorAll按类进行选择,然后只使用JavaScript查找第10个元素。当jQuery必须在纯JavaScript中进行选择时,它会使用Sizzle引擎,这个引擎非常快,但不会比浏览器中的本地代码快。所以再一次,简短的回答是,它们是一样的,长的回答是,看情况而定。如果您对属于这一类的所有扩展感兴趣,我所包含的jQuery文档链接列出了它们。

首先,是的,nikhill是对的。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();

就是这样!