альтернатива 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>