Використання селектора "починається з" для назв окремих класів


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, оскільки клас першого діва повертається як рядок (я думаю) і насправді не починається з 'apple-', а швидше 'some-'

Один із способів цього не використовувати, починається з, а натомість містить:

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

Проблема в тому, що він також вибере третій DIV на моєму прикладі.

Запитання: Через jQuery, що є правильним способом використання селекторів предикатів для назв окремих класів, а не атрибутів всього класу як рядка? Це лише питання захоплення КЛАСУ, а потім розділення його на масив, а потім циклічного перегляду кожного окремого з допомогою регулярного вираження? Або є більш елегантне / менш багатослівне рішення?

Відповіді:


304

Класи, які починаються з "яблуко" плюс класи, які містять "яблуко"

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

5
+1. Хоча я згоден з пропозицією @parrots про те, що "яблуко" має бути тут власним класом, оскільки воно, очевидно, перекриває декілька дівок, але все ж є чіткою сутністю. Але це все-таки вирішує проблему.
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
komponenthouse.com/article-19 : Якщо ви подивитеся на розділ get by class, використання звичайного синтаксису крапок зазвичай є пристойним бітом швидше, ніж трактування класу як атрибута. Додайте пошук підрядків (і додаткову роботу, яку йому доведеться виконати, щоб розбити елементи з кількома іменами класів), і це призведе до гідної економії продуктивності.
Папуги

1
Я згоден. Зрозуміло, що ми все ще активно підтримуємо IE6, і він не підтримує селектори у CSS: .class1.class2.class3 як такі, ми покладаємось на використання більш довгих імен класів, де 'параметри' діляться тире.
DA.


6

Хоча головна відповідь тут є вирішенням конкретного випадку запитувача, якщо ви шукаєте рішення, як насправді використовувати "починається з" у назвах окремих класів:

Ви можете використовувати цей спеціальний селектор jQuery, який я називаю :acp()"Префікс класу". Код знаходиться внизу цієї публікації.

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

Тут будуть обрані будь-які <div>елементи, які мають принаймні одне ім’я класу, що починається із заданого рядка ("start_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>

у цьому випадку як питання Джоша Стодола відповідь правильна. Класи, які починаються з "яблуко" плюс класи, які містять "яблуко"

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

може бути, це допомагає ще одному спасибі


0

Якщо в елементі є декілька класів, "[class ^ = 'apple-']" не працює, наприклад

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

ОП згадує це у запитанні.
Гусь
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.