У меня есть структура HTML с тремя структурами некоторого элемента и двумя p справа:

<some_tag></some_tag>
<p></p>
<p></p>

<some_tag></some_tag>
<p></p>
<p></p>

<some_tag></some_tag>
<p></p>
<p></p>

На практике у меня гораздо больше, чем просто три структуры (более тридцати), поэтому мне нужна автоматизация.

Мне нужно выбрать каждый последний p в первых двух структурах, но не последний p в последней структуре.

Моя проблема

Кажется, нет никакого CSS-способа сделать выбор, который я желаю.

Рассматривая HTML-способ обертывания каждой не последней, some_tag структуры в какой-то другой элемент (например, div), я пришел к выводу, что мне не нравится это решение, поскольку оно кажется мне неэстетичным.

Мой вопрос

Знаете ли вы способ автоматизации описанного выбора с помощью JavaScript?

-1
user3578082 21 Авг 2018 в 08:26

4 ответа

Лучший ответ

Вы можете сделать это с помощью JavaScript, вот пример:

const elements = document.querySelectorAll("*");
let latestParagraph;
const paragraphsToStyle = [];

for(const element of elements){
  if(element.tagName === "P"){
    latestParagraph = element;
  }else{
    if(latestParagraph){
      paragraphsToStyle.push(latestParagraph);
    }
  }
}

paragraphsToStyle.pop();

for(const paragraph of paragraphsToStyle){
  paragraph.style.color = "red";
}
<h3>h</h2>
<p>p1</p>
<p>p2</p>
<h2>h</h2>
<p>p3</p>
<p>p4</p>
<h1>h</h2>
<p>p5</p>
<p>p6</p>

Это будет работать, только если нет вложенности.

Скрипт проходит через все элементы на странице и, когда встречается элемент без абзаца, добавляет последний найденный абзац в массив paragraphsToStyle. В конце первого цикла последний абзац на странице удаляется из массива paragraphsToStyle.pop()

1
JohnDoea 21 Авг 2018 в 10:05

Ваш макет создан динамически? Вы всегда можете использовать классы CSS, чтобы справиться с этим легко. Если вы не можете управлять этим с помощью макета, вот быстрый способ сделать это:

#myLayout *:not(:last-child) > p:last-child {
  color: red
}

Этот код захватывает каждого родителя с p-ребенком. Следует игнорировать последнего дочернего брата и всегда брать последний р. Я бы порекомендовал заменить * на узел или селектор CSS, чтобы предотвратить неожиданные результаты. Я также рекомендую по крайней мере ограничить возможные проблемы, заключив все в контейнер, как показано ниже.

<div id="myLayout">
  <div>
    <h2>h1</h2>
    <p>p1</p>
    <p>p2</p>
  </div>
  <div>
    <h2>h1</h2>
    <p>p1</p>
    <p>p2</p>
  </div>
  <div>
    <h2>h1</h2>
    <p>p1</p>
    <p>p2</p>
  </div>
</div>
0
Robert 21 Авг 2018 в 05:55

Изменить . Как уже упоминали другие пользователи, вы можете реструктурировать свой HTML-код, чтобы он легче работал с селекторами. Но если это невозможно, вы можете использовать JavaScript для этого. В этом случае все, что вам нужно сделать, это посмотреть, является ли элемент тегом «p» и не является ли следующий элемент тегом «p»:

var children = document.getElementById('content').children;
for (let i = 0; i < children.length - 1; i++) {
  let nextTagName = children[i+1].tagName;
  if (children[i].tagName === 'P' && nextTagName !=='P') {
      children[i].classList.add('selected');
  }
}
.selected {
  color: aqua;
}
<div id="content">
    <h2>Heading 1</h2>
    <p>p 1</p>
    <p>p 2</p>
    <h3>Heading 2</h3>
    <p>p 3</p>
    <p>p 4</p>
    <h4>Heading 3</h4>
    <p>p 5</p>
    <p>p 6</p>
</div>
-1
Steve 21 Авг 2018 в 06:12

Это не очень хорошая структура HTML для того, что вы хотите сделать. Будет намного проще, если вы поместите каждый набор hX и p в тег контейнера, например, div.

В противном случае вам придется зацикливаться на каждом элементе с помощью JavaScript и решать, применять ли стили (если текущий элемент является p, и есть следующий элемент, а это не p).

2
We Are All Monica 21 Авг 2018 в 05:46
51942088