Выбор класса и первых 3 остальных; nth-child и nth-of-type бесполезны - программирование
Подтвердить что ты не робот

Выбор класса и первых 3 остальных; nth-child и nth-of-type бесполезны

У меня есть элемент DOM (#installations) с количеством детей, только один из них имеет класс .selected. Мне нужно выбрать этот класс и первые 3 из остальных (: not (.selected)) и показать их - цель состоит в том, чтобы отображать только 4 элемента, независимо от того, какой элемент имеет класс .selected.

Проблема заключается в выражении:

#installations > *:not(.selected):nth-of-type(-n+3), .selected

: nth-of-type() игнорирует селектор: not() и просто выбирает первые 3 дочерних элемента #installation. Например, если у меня есть этот HTML:

<div id="installations">
    <div id="one"/>
    <div id="two"/>
    <div id="three" class="selected"/>
    <div id="four"/>
    <div id="five"/>
</div>

У меня будет только один, два, три, а не первые четыре. Логическим следствием является то, что nth-of-type() будет иметь только (один, два, четыре, пять), из которых: not() уже исключил выбранный, выбрав (один, два, четыре) а затем другая часть селектора , .selected добавит выбранный элемент.

Если выбрано не в первых четырех элементах, скажем, шестое, мы будем выбирать первые три + шестой.

Чтобы уточнить: выбор выделенного плюс 3 смежных элемента также прекрасен. Тем не менее, это тоже сложно в случае, если вы выбрали последние 3 (если мы выберем следующие 3 смежных элемента)

4b9b3361

Ответ 1

Как упоминалось в моем комментарии, псевдоклассы не обрабатываются последовательно; все они оцениваются вместе над каждым из ваших элементов. Подробнее см. этот ответ.

После небольшого поворота, учитывая ваш HTML и условия, с помощью которых можно выбрать элементы, я придумал следующий длинный список селекторов:

/* The first three children will always be selected at minimum */
#installations > div:nth-child(-n+3),
/* Select .selected if it not among the first three children */
#installations > div.selected,
/* If .selected is among the first three children, select the fourth */
#installations > div.selected:nth-child(-n+3) ~ div:nth-child(4)

Для этого нужно сделать одно простое предположение: класс selected будет отображаться только по одному элементу за раз.

Вам нужно будет объединить все три селектора в том же правиле, чтобы соответствовать четырем элементам, которые вы ищете. Обратите внимание на запятые в моем коде.

Интерактивная демонстрация jsFiddle (для тестирования селектора с классом в разных дочерних элементах)


Для чего это стоит, проще, если вы можете вернуться к JavaScript. В качестве примера, если вы используете jQuery, его :lt() селектор делает вещи немного проще:

// Apply styles using this selector instead: #installations > div.with-jquery
$('#installations')
    .children('div.selected, div:not(.selected):lt(3)')
    .addClass('with-jquery');

Интерактивная демонстрация jsFiddle (проигнорируйте JS-код в этой демонстрации, он только там, чтобы сделать его интерактивным)

Ответ 2

То, что вам нужно использовать, - это смежные селекторные функции. Вот пример, который я приготовил, который работает в Safari (не тестировался в другом месте). Отображаются только элементы "Два", "Три" и "Четыре".

<!DOCTYPE html>
<html>
  <head>
    <style>
      .the-list li {display:none;}
      .the-list li.selected {display:block;}
      .the-list li.selected + li {display:block;}
      .the-list li.selected + li + li {display:block;}
    </style>
  </head>
  <body>
    <ol class='the-list'>
      <li>One</li>
      <li class='selected'>Two</li>
      <li>Three</li>
      <li>Four</li>
      <li>Five</li>
      <li>Six</li>
    </ol>
  </body>
</html>