хитрый css-селектор


альтернатива jQuerys nextUntil()

Сегодня я столкнулся с простой на первый взгляд проблемой:

  • абзацы под каждым заголовком h2 должны иметь разный цвет текста
    • образец1-1 – образец1-3 -> синий
    • sample2-1 to sample2-2 -> красный
    • образец3-1 -> зеленый
  • щелчок на h2 должен переключать отображение непосредственно следующих параграфов
<!DOCTYPE html>
<html lang=en>
  <meta charset=UTF-8>
  <title>Document</title>
  <h1>Sample</h1>
    <h2>sample-1</h2>
      <p>sample1-1
      <p>sample1-2
      <p>sample1-3
    <h2>sample-2</h2>
      <p>sample2-1
      <p>sample2-2
    <h2>sample-3</h2>
      <p>sample3-1
  <h3>Note</h3>
  <p>the paragraphs under each header2
  <p>need a different text color 
  <p>test1-1 to test1-3 -> blue
  <p>test2-1 to test2-2 -> red
  <p>test3-1 -> green
  <p>a click on h2 must toggle display the direct
  <p>following paragraphs
Вход в полноэкранный режим Выйти из полноэкранного режима

Хорошо, давайте начнем с цветов,
и напишем несколько простых правил css,
Общий селектор братьев и сестер (~)
мой друг :-):

h2:first-of-type~p {color:blue}
h2:nth-of-type(2)~p {color:red}
h2:nth-of-type(3)~p {color:green}
Вход в полноэкранный режим Выйти из полноэкранного режима

Готово, цвета под соответствующим h2 правильные. К сожалению, абзацы под следующим h3 также становятся зелеными.
Я не учел, что общий селектор братьев и сестер (~) выбирает все следующие абзацы.

Что мне делать?

  • Мне нужен первый элемент h2 h2:nth-of-type(1).
  • все следующие абзацы ~p
  • но не следующие абзацы за вторым h2.

Хорошо, сначала я пытаюсь выбрать все следующие абзацы после второго h2

  • выбрать все абзацы за первым h2 h2:nth-of-type(1)~*
  • но не p (он выбирает только заголовки h2,h2,h3)
  • но мне нужны следующие параграфы с ~p
  • обобщенный h2:nth-of-type(1)~*:not(p)~p

Поэтому полный селектор выглядит следующим образом:

h2:nth-of-type(1)~p:not(h2:nth-of-type(1)~*:not(p)~p)
Войти в полноэкранный режим Выйти из полноэкранного режима

и css для раскрашивания абзацев

h2:nth-of-type(1)~p:not(h2:nth-of-type(1)~*:not(p)~p){
  color:blue;
}
h2:nth-of-type(2)~p:not(h2:nth-of-type(2)~*:not(p)~p){
  color:red;
}
h2:nth-of-type(3)~p:not(h2:nth-of-type(3)~*:not(p)~p){
  color:green;
}
Войти в полноэкранный режим Выйти из полноэкранного режима

проблема переключения отображения

дайте h2 курсор-указатель и создайте класс для переключения отображения

h2{
  cursor: pointer;
  user-select:none;
}
.no-display{
  display:none;
}
Войти в полноэкранный режим Выход из полноэкранного режима

Остальное уже не является настоящей проблемой, поскольку мы уже создали соответствующие селекторы в предыдущем шаге:

"use strict";

  document.querySelectorAll('h2')
    .forEach(( node, index ) =>
      node.addEventListener ( 'click', () =>
        document.querySelectorAll(
        `h2:nth-of-type(${index+1})~p:not(h2:nth-of-type(${index+1})~*:not(p)~p)`
        )
          .forEach(node => node.classList.toggle('no-display'))
      )
  )

Войти в полноэкранный режим Выход из полноэкранного режима

Полный код:

<!DOCTYPE html>
<html lang=de>
  <meta charset=UTF-8>
  <title>Document</title>
  <style>

    h2:nth-of-type(1)~p:not(h2:nth-of-type(1)~*:not(p)~p){
      color:blue;
    }
    h2:nth-of-type(2)~p:not(h2:nth-of-type(2)~*:not(p)~p){
      color:red;
    }
    h2:nth-of-type(3)~p:not(h2:nth-of-type(3)~*:not(p)~p){
      color:green;
    }

    h2{
      cursor: pointer;
      user-select:none;
    }
    .no-display{
      display:none;
    }

  </style>
  <h1>Sample</h1>
    <h2>Test-1</h2>
      <p>test1-1
      <p>test1-2
      <p>test1-3
    <h2>Test-2</h2>
      <p>test2-1
      <p>test2-2
    <h2>Test-3</h2>
      <p>test3-1
  <h3>Note</h3>
  <p>the paragraphs under each header2
  <p>need a different text color 
  <p>test1-1 to test1-3 -> blue
  <p>test2-1 to test2-2 -> red
  <p>test3-1 -> green
  <p>a click on h2 must toggle display the direct
  <p>following paragraphs

  <script>
  "use strict";

  document.querySelectorAll('h2')
    .forEach(( node, index ) =>
      node.addEventListener ( 'click', () =>
        document.querySelectorAll(
        `h2:nth-of-type(${index+1})~p:not(h2:nth-of-type(${index+1})~*:not(p)~p)`
        )
          .forEach(node => node.classList.toggle('no-display'))
      )
  )

  </script>
Вход в полноэкранный режим Выход из полноэкранного режима

Оцените статью
Procodings.ru
Добавить комментарий