Подстановочный знак CSS, не влияющий на стиль

#javascript #jquery #html #css #css-selectors

#javascript #jquery #HTML #css #css-селекторы

Вопрос:

Я пытаюсь создать стиль div, используя селектор подстановочных знаков CSS. Так я и сделал div[class^="list_"] . Но следующий код не работает

 $('.box2').addClass(function() {
  return 'list_'   $('.box1 li').length;
});  
 div[class^="list_"] {
  color: red;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="box1">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
<div class="box2">text</div>  

Но когда я делаю

 div[class^=".box2 list_"] {
    color: red;
}
  

это влияет на стиль. Насколько я понимаю, у div которых есть класс, начинающийся с list_ , будет этот стиль.Но не могу понять, почему мне нужно добавить .box2 в этот селектор подстановочных знаков

Комментарии:

1. Полагаться на class атрибут для перечисления классов в любом определенном порядке очень хрупко. ^= Оператор означает, что вы ожидаете, что class значение будет начинаться с некоторой строки. Код, который, по вашим словам, работает, на самом деле не будет работать из-за этого . перед «box2», но без этого он будет работать, потому что .addClass() добавляет желаемое содержимое атрибута класса в конец значения атрибута.

2. Ваш селектор пытается сопоставить значение атрибута class в начале с ^= . Попробуйте *= , который ищет совпадение в любом месте значения атрибута класса.

3. Вам действительно было бы лучше добавить два класса: один, чтобы указать, что <div> был затронут, например «has_list», и один для определенного количества, как у вас есть сейчас. Таким образом, вы можете просто написать свой селектор CSS как div.has_list

4. Это проблема с селекторами атрибутов, хотя комментарий @hungerstar решит вашу проблему, вы также столкнетесь с другой проблемой, которая также может соответствовать таким классам, как list_not-needed-to-be-style или a-list_1 . Я бы согласился с комментарием pointy о 2 отдельных классах

Ответ №1:

Вы должны использовать * вместо ^ . Согласно MDN

[attr^=value] Представляет элементы с именем атрибута attr, значение которого имеет префикс (предшествующий) value
[attr*=value] Представляет элементы с именем атрибута attr, значение которого содержит по крайней мере одно вхождение значения в строке

 $('.box2').addClass(function() {
  return 'list_'   $('.box1 li').length;
});  
 div[class*="list_"] {
  color: red;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="box1">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
<div class="box2">text</div>  

Ответ №2:

Попробуйте *= . Который ищет совпадение в любом месте значения атрибута класса.

Ваш текущий селектор, ^= , пытается соответствовать значению атрибута class в начале.

Смотрите: Селекторы атрибутов — MDN

 $('.box2').addClass(function() {
  return 'list_'   $('.box1 li').length;
});  
 div[class*="list_"] {
  color: red;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="box1">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
<div class="box2">text</div>  

Как отмечали другие в комментариях, селекторы атрибутов могут быть скользкими в зависимости от того, как они реализованы. В этом случае, как упоминал @Pointy, вы можете захотеть добавить два класса. Один для подсчета и один для обозначения того, что он изменился.

Вы также могли бы добавить data- атрибут вместо класса. Что-то вроде data-list-count . Тогда ваш селектор был бы [data-list-count] .

Ответ №3:

^= выбирает элемент с атрибутом class , который начинается с следующей строки. Вы можете использовать *= селектор для выбора класса, который содержит:

 $('.box2').addClass(function() {
  return 'list_'   $('.box1 li').length;
});  
 div[class*="list_"] {
  color: red;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="box1">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
<div class="box2">text</div>  


Но я бы никогда не стал полагаться на такую конструкцию — вместо этого используйте новый класс (скажем, list основанный на вашей бизнес-логике), а затем вы можете использовать .box2.list вместо этого для специфичности (обратите внимание, что после точки нет пробела):

 $('.box2').addClass(function() {
  // your business logic determining which class to add
  return 'list';
});  
 .box2.list {
  color: red;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="box1">
  <li>a</li>
  <li>b</li>
  <li>c</li>
</ul>
<div class="box2">text</div>