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;
});
}
Есть ли более чистый способ? Здесь рабочая скрипка выше
Ответы
Ответ 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");
Он также работает для случая, когда кто-то создает класс с точкой в середине.