在单个类名上使用“开头为”选择器


157

如果我有以下内容:

<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

我可以使用以下选择器找到前两个DIV:

$("div[class^='apple-']")

但是,如果我有这个:

<div class="some-other-class apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

它只会找到第二个DIV,因为第一个div的类是作为字符串返回的(我认为),并且实际上不是以“ apple-”开头,而是以“ some-”开头

解决该问题的一种方法是不使用开头为,而是包含:

$("div[class*='apple-']")

问题在于它还会在我的示例中选择第三个DIV。

问题:通过jQuery,对单个类名而不是整个类属性作为字符串使用谓词选择器的正确方法是什么?只是获取CLASS,然后将其拆分为一个数组,然后使用正则表达式遍历每个单独的问题?还是有一个更优雅/更简洁的解决方案?

Answers:


303

以“ apple-”开头的类以及包含“ apple-”的类

$("div[class^='apple-'],div[class*=' apple-']")

5
+1。尽管我同意@parrots的建议,在这里“ apple”应该是其自己的类,因为它显然与多个div重叠,但却是一个独特的实体。但这确实解决了问题。
jvenema'2

嗯...聪明!我没想到要在那里使用空间。可以在jQuery选择器中使用布尔运算符吗?理想情况下,上述方法将是“ OR”,以避免(罕见且可能可以避免的)情况,其中有多个班级盯着“ apple
DA。

不确定我是否了解,但是如果您只想在第一个选择器返回零元素时使用第二个选择器,则可以执行以下操作: var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Josh Stodola 2010年

现在,我考虑了一下,您的初始解决方案就可以了。具有“ apple-brick apple-horse”之类的类的DIV仍仅会被选择到jQuery对象中一次。
DA。

如果不限制特定元素的类,请使用*代替div :)
Hidayt Rahman

13

我建议将“苹果”作为自己的课程。如果可以的话,应该避免使用“开始于” /“结束于”,因为能够选择“使用” div.apple会更快。那是更优雅的解决方案。如果它使任务更简单/更快,请不要害怕将它们分成单独的类。


您如何看待它会更快?它仍然必须扫描整个DOM并评估class属性。这将稍微快一些(最好),因为它不必对class属性进行子字符串化。微不足道。
Josh Stodola'2

2
componenthouse.com/article-19:如果您在“按类获取”部分中查找,使用常规点语法通常比将类视为属性要快一些。添加子字符串搜索(以及他需要做的额外工作,以分解具有多个类名的元素),这将节省大量的性能。
鹦鹉

1
我同意。问题在于,我们仍在大力支持IE6,并且不支持CSS中的复合选择器:.class1.class2.class3如此,我们依赖于使用更长的类名,其中“参数”用破折号分隔。
DA。


6

尽管这里的最佳答案是针对问询者的特殊情况的解决方法,但如果您正在寻找一种针对各个类名实际使用“开头为”的解决方案,请执行以下操作:

您可以使用此自定义jQuery选择器,我将其称为:acp()“ A Class Prefix”。代码在这篇文章的底部。

var test = $('div:acp("starting_text")');

这将选择<div>具有至少一个以给定字符串(在此示例中为“ starting_text”)开头的类名的所有元素,而不管该类是在类属性字符串的开头还是其他位置。

<div id="1" class="apple orange lemon" />
<div id="2" class="orange applelemon banana" />
<div id="3" class="orange lemon apple" />
<div id="4" class="lemon orangeapple" />
<div id="5" class="lemon orange" />

var startsWithapp = $('div:acp("app")');

这将返回元素1、2和3,但不返回 4或5。

这是:acp自定义选择器的声明,您可以将其放置在任何地方:

$(function(){
    $.expr[":"].acp = function(elem, index, m){
          var regString = '\\b' + m[3];
          var reg = new RegExp(regString, "g");
          return elem.className.match(reg);
    }
});

我这样做是因为我对没有后端控制的网站进行了很多GreaseMonkey黑客操作,因此我经常需要查找具有动态后缀的类名的元素。这非常有用。


2

试试这个:

$("div[class]").filter(function() {
    var classNames = this.className.split(/\s+/);
    for (var i=0; i<classNames.length; ++i) {
        if (classNames[i].substr(0, 6) === "apple-") {
            return true;
        }
    }
    return false;
})

2
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>

在这种情况下,乔什·斯托多拉(Josh Stodola)的问题是正确的,以“ apple-”开头的类以及包含“ apple-”的类

$("div[class^='apple-'],div[class*=' apple-']")

但是如果元素具有多个这样的类

<div class="some-class apple-monkey"></div>
<div class="some-class apple-horse"></div>
<div class="some-class cow-apple-brick"></div>

那么Josh Stodola的解决方案将无法正常工作,
因为它必须做这样的事情

$('.some-parent-class div').filter(function () {
  return this.className.match(/\bapple-/);// this is for start with
  //return this.className.match(/apple-/g);// this is for contain selector
}).css("color","red");

可能对别人有帮助吗


0

如果元素具有多个类,则“ [class ^ ='apple-']”类将不起作用,例如

<div class="fruits apple-monkey"></div>

OP确实在问题中提到了这一点。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.