Подтвердить что ты не робот

JQuery - имеет класс, который начинается с

Каким будет лучший способ получить все div, у которых есть класс, начинающийся с input? Другими словами, a и b должны быть возвращены из приведенного ниже, но не 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;
    });
}

Есть ли более чистый способ? Здесь рабочая скрипка выше

4b9b3361

Ответ 1

Вы можете создать собственное выражение в jQuery

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

и вы можете получить эти div с помощью

$('div:hasClassStartingWithInput');

a Пример 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/

Ответ 2

Вот один из способов...

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() применяется только к тем div, которые, как вы знаете, имеют input где-то в классе, производительность улучшится.

Или универсальная версия будет выглядеть так:

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

Ответ 3

Это мое решение проблемы:

(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");

Он также работает для случая, когда кто-то создает класс с точкой в ​​середине.