Выбор класса и первые 3 из остальных; nth-child и nth-of-type бесполезны - PullRequest
16 голосов
/ 26 декабря 2011

У меня есть элемент 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 добавит выбранный элемент.

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

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

Ответы [ 2 ]

35 голосов
/ 26 декабря 2011

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

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

/* The first three children will always be selected at minimum */
#installations > div:nth-child(-n+3),
/* Select .selected if it's 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 будет появляться только для одного элемента за раз.

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

Интерактивная демонстрация 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 вэто демо, оно только для интерактивности)

0 голосов
/ 26 декабря 2011

То, что вам нужно использовать, это соседние селекторы. Вот пример, который я приготовил, который работает в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...