Есть ли селектор CSS, эквивалентный JS querySelector? - PullRequest
2 голосов
/ 03 октября 2019

РЕДАКТИРОВАТЬ: Этот вопрос аналогичен моему, но это не совсем дубликат, потому что я понимаю, как на самом деле работают псевдо-селекторы :first-child и :first-of-type. Вопрос не в том, «почему мои селекторы не работают», а в том, «Какой селектор помимо просто простой :first-child я могу использовать для моих обстоятельств?»Принятый ответ на этот вопрос просто объясняет информацию, которую я уже знаю.

===

В JavaScript, когда вы используете element.querySelector('a'), он вернет первый тег <a>, найденный внутриэлемент, независимо от его глубины, и он не будет продолжать поиск других элементов.

В CSS вы можете использовать пробел, такой как .element a, и он будет применяться к каждому найденному тегу <a>внутри элемента, независимо от того, насколько глубоко. Это больше похоже на element.querySelectorAll('a'), если сравнивать его с JavaScript.

Даже .element > a применяется к каждому тегу <a>, который является прямым потомком элемента, но все еще не совсем правильным и Я бы предпочел не зависеть от уровня вложенности. .element a:first-child ближе, но все еще не идеально. Это все еще применяется к нескольким элементам, если ваша структура выглядит следующим образом:

<span class="element">
  <span>
    <a>Demo</a> <!-- I only want to select this one -->
    <a>Demo</a>
  </span>
  <span>
    <a>Demo</a>
    <a>Demo</a>
  </span>
</span>

В приведенном выше примере вы можете гипотетически использовать .element > span:first-child > a:first-child, но это становится чрезвычайно жестким и сильно зависитна структуру вложенности, которая в моем случае изменяется в зависимости от места, в котором она появляется в документе. Обычно я настраиваю HTML, чтобы иметь более согласованную и более простую структуру, но у меня нет этой свободы в настоящее время, мне просто нужно работать с тем, что доступно.

Есть ли какая-то магия CSS, которую яможно использовать для выбора только первого совпадения независимо от глубины? Или мне просто нужны дополнительные классы?

1 Ответ

3 голосов
/ 03 октября 2019

Нет ни одного селектора, который бы покрывал это.

Таким образом, у вас есть два варианта: либо добавить класс, либо использовать этот трюк, где вы МОЖЕТЕ применить стилизацию так, чтобы она отображалась визуальновоздействовать только на те элементы, которые вам интересны.

Идея состоит в том, чтобы просто получить его наполовину справа с первым селектором .element a:first-of-type, а затем переопределить / восстановить те, которые были неправильно сопоставлены со вторым селектором.element :not(:first-child) a - это также будет соответствовать <a> тэгам, которые не были first-of-type, поэтому кажется хорошим местом для размещения вашего стиля по умолчанию вместе с .element a, чтобы покрыть остальные.

.element {
  display: block;
}

/* first <a> tags to appear at any level turn blue */
.element a:first-of-type {
  color: blue;
}

/* "restore" styling on <a> tags with any parent that isn't the first child */
/* also, set default styling in one place */
.element :not(:first-child) a,
.element a {
  color: black;
}
<span class="element">
  <span>
    <a>Demo</a> <!-- Select this one -->
    <a>Demo</a>
  </span>
  <span>
    <a>Demo</a>
    <a>Demo</a>
  </span>
</span>

<span class="element">
  <span>
    <span>
      <a>Demo</a> <!-- Select this one, further nested -->
      <a>Demo</a>
    </span>
  </span>
  <span>
    <a>Demo</a>
    <a>Demo</a>
  </span>
</span>
...