jQuery - 拥有以某个类开头的类名

12

如何获取所有具有以 input 开头的任何类的 div 元素?换句话说,从下面的内容中应返回 ab,但不应返回 c

<div id="a" class="input1 foo"></div>
<div id="b" class="foo input2"></div>
<div id="c" class="xinput3 foo"></div>

这里提供了一个貌似可行的方法,惊人地被接受了。那就是使用$("div[class^='input']");,但显然这样会漏掉b。当然,$("div[class*='input']");会在c上产生误判。

我能想到的最好办法就是下面这个怪胎:

function getAllInputDivs() {
    return $("div").filter(function (i, currentDiv) {
        return $.grep($(currentDiv).attr("class").split(" "), function (val) {
            return val.substr(0, "input".length) === "input";
        }).length > 0;
    });
}

有没有更简洁的方法?这里有一个上面代码的演示


我认为在拥有像input1和input2这样的东西时,classnames并不是最好的选择。如果输入足够独特以被枚举,您可以使用ID或名称,这些可以使用$("[id^=input]")进行选择。 - Kevin B
类似的问题:jQuery选择器以前缀为开头来定位任何具有多个存在的类名?但我以前没有制作过自定义选择器表达式,所以我很喜欢这个问题的答案 :) - BoltClock
1
@BoltClock:自定义选择器会破坏 querySelectorAll。它们不值得这样做。 - user1106925
1
@–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–ĖÔľöÁ°ģŚģ쌶āś≠§„Äā - BoltClock
@ЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖΞЖ - 我想我终于明白你的观点了。你是说当你使用自定义选择器时,jQuery能够使用本地(可能快速)的querySelectAll吗? - Adam Rackis
显示剩余4条评论
3个回答

22

您可以在jQuery中创建自己的表达式。

$.expr[':'].hasClassStartingWithInput = function(obj){
  return (/\binput/).test(obj.className);
};

你可以使用以下代码检索这些 div:

$('div:hasClassStartingWithInput');

一个 JsFiddle 示例:http://jsfiddle.net/7zFD6/


编辑:你也可以使用参数(不要在函数标识符内硬编码类名)以这种方式实现。

$.expr[':'].hasClassStartingWith = function(el, i, selector) {
  var re = new RegExp("\\b" + selector[3]);
  return re.test(el.className);
}

http://jsfiddle.net/pMepk/1/上有一个新的示例。


1
那个\b不应该改成^吗? - Blazemonger
1
我认为\b在某些(狭窄)情况下可能会失败,因为一个类可能包含被解释为单词边界的字符。比如my.input,它是一个有效的类。 - user1106925
1
@–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ėőě–Ė - śąĎŚŹĮšĽ•śé•ŚŹóŤŅôšļõÁč≠Á™ĄÁöĄšĺ茧Ė„ÄāśąĎśó†ś≥ēśÉ≥ŤĪ°Ťá™Ś∑ĪšľöśÉ≥Ť¶ĀŚąõŚĽļšłÄšł™Śźćšłļmy.inputÁöĄÁĪĽŚźć„Äā - Adam Rackis
1
@FabrizioCalderan 括号序列,比如 (( 或者 ((( 会降低代码的可读性(个人观点)- 我尽可能地去掉它们... - Šime Vidas
@FabrizioCalderan,示例#2返回一个对象,而我想要布尔值。您能否解释一下参数el,i,selector的工作原理?谢谢。 - 5ervant - techintel.github.io
显示剩余8条评论

6
这是一种方法...
function getAllInputDivs() {
    return $("div").filter(function () {
        return /(?:^|\s)input/.test(this.className);
    });
}

或者让它更加多用途...
function classStartsWith( tag, s ) {
    var re = new RegExp('(?:^|\\s)' + s);
    return $(tag || '*').filter(function () {
        return re.test(this.className);
    });
}

如果您不喜欢正则表达式,也可以采用indexOf方法...
function classStartsWith( tag, s ) {
    return $(tag || '*').filter(function () {
        return this.className.indexOf(s)===0 || this.className.indexOf(' ' + s)>-1;
    });
}

需要注意的是,它只测试空格字符,不测试制表符,因此如果使用制表符而不是空格,则可能失败。


回到正则表达式版本,您可以通过将搜索字符串添加到选择器中来提高效率。

然后它只测试 div 的子集。

function getAllInputDivs() {
    return $("div[class*='input']").filter(function () {
        return /(?:^|\s)input/.test(this.className);
    });
}

使用.filter()只应用于那些你知道类中某处有input的div,性能会得到提升。

或者多才多艺版本看起来是这样的:

function classStartsWith( tag, s ) {
    var re = new RegExp('(?:^|\\s)' + s);
    return $((tag || '*') + '[class*="' + s + '"]').filter(function () {
        return re.test(this.className);
    });
}

1
+1 - 很好 - 看起来你修复了Fabrizio回答中的正则表达式。 - Adam Rackis

2
这是我对这个问题的解决方案:
(function($) {
    $.fn.hasClassStartsWith = function(klass) {
    var _return = [];
    for(var i = 0; i < this.length; i++){
        if((' ' + $(this[i]).attr('class')).indexOf(klass) != -1)
            _return.push(this[i]);
    }
    return _return;
    }
})(jQuery);

使用方法如下:

var divs = $('div').hasClassStartsWith("my_class_prefix");

如果有人创建了一个带有点号的类,这个方法也适用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接