Использование селектора «начинается с» для отдельных имен классов

158

Если у меня есть следующее:

<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-']")

Проблема в том, что он также выберет 3-й DIV в моем примере.

Вопрос: С помощью jQuery, как правильно использовать селекторы предикатов для отдельных имен классов, а не весь атрибут класса в виде строки? Это просто вопрос захвата КЛАССА, затем разделения его на массив и затем повторения каждого отдельного с помощью регулярных выражений? Или есть более элегантное / менее подробное решение?

DA.
источник

Ответы:

304

Классы, которые начинаются с «apple-» плюс классы, содержащие «apple-»

$("div[class^='apple-'],div[class*=' apple-']")
Джош Стодола
источник
5
+1. Хотя я согласен с предложением @parrots о том, что «яблоко» должно быть здесь своим собственным классом, поскольку оно, очевидно, перекрывает несколько элементов div, но является отдельной сущностью. Но это решает проблему.
Jvenema
Хм ... умный! Я не думал об использовании там места. Можно ли использовать логические операторы в селекторе jquery? В идеале, выше было бы «ИЛИ», чтобы избежать (редкого и, вероятно, предотвратимого) случая, когда существует более одного класса, начинающего с «яблока»
DA.
Не уверен, что понимаю, но если вы хотите использовать второй селектор только тогда, когда первый селектор возвращает ноль элементов, вы можете сделать что-то вроде этого: var divs = $("div[class^='apple-']"); if(divs.length == 0) divs = $("div[class*=' apple-']");
Джош Стодола
теперь, когда я думаю об этом, ваше первоначальное решение работает просто отлично. DIV с таким классом, как «яблочно-кирпичная лошадь», все равно будет выделен один раз в объект jQuery.
DA.
используйте * вместо div, если вы не ограничиваете класс для определенного элемента :)
Hidayt Rahman
13

Я бы порекомендовал сделать «яблоко» своего класса. Вы должны избегать начала с / конца, если можете, потому что возможность выбора с использованием div.appleбудет намного быстрее. Это более элегантное решение. Не бойтесь разбивать вещи на отдельные классы, если это делает задачу проще / быстрее.

Попугаи
источник
Как вы думаете, это будет намного быстрее? Он все еще должен сканировать весь DOM и оценить атрибут класса. Это было бы немного быстрее (в лучшем случае), потому что не нужно было бы вставлять атрибут класса. Незначительно.
Джош Стодола
2
componententhouse.com/article-19 : Если вы заглянете в раздел «get by class», то использование синтаксиса с обычной точкой обычно немного быстрее, чем обработка класса как атрибута. Добавьте поиск по подстроке (и дополнительную работу, которую он должен будет выполнить, чтобы выделить элементы с несколькими именами классов), и это приведет к приличной экономии производительности.
Попугаи
1
Я согласен. Суть в том, что мы все еще активно поддерживаем IE6, и он не поддерживает составные селекторы в CSS: .class1.class2.class3 как таковой, мы полагаемся на использование более длинных имен классов, где «параметры» делятся на тире.
DA.
6

это для префикса с

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

это для начала, так что вам не нужно иметь символ '-' там

$("div[class|='apple']")

Вы можете найти множество других интересных вариантов селектора jQuery здесь https://api.jquery.com/category/selectors/

Mexicoder
источник
6

Хотя верхний ответ здесь - это обходной путь для конкретного случая спрашивающего, если вы ищете решение для фактического использования «начинается с» в именах отдельных классов:

Вы можете использовать этот пользовательский селектор jQuery, который я называю :acp()«Префикс класса». Код находится внизу этого поста.

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

При этом будут выбраны все <div>элементы, у которых есть хотя бы одно имя класса, начинающееся с заданной строки (в этом примере «стартовый_текст»), независимо от того, находится ли этот класс в начале или где-либо еще в строках атрибута класса.

<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, на которых у меня нет внутреннего контроля, поэтому мне часто нужно находить элементы с именами классов, которые имеют динамические суффиксы. Это было очень полезно.

equazcion
источник
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>

в этом случае на вопрос Джоша Стодола ответ правильный. Классы, начинающиеся с «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>

тогда решение Джоша Стодола не будет работать,
для этого нужно сделать что-то вроде этого

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

может быть, это помогает кому-то еще спасибо

code.rider
источник
0

Если элемент имеет кратные классы "[class ^ = 'apple-']" не работает, например

<div class="fruits apple-monkey"></div>
Рамон Мтц
источник
ФП упоминает об этом в вопросе.
Гусь