简体   繁体   中英

Vanilla JS: Add Class When A Different Class Is Under An Element

What I'm looking to do is add a class to a specific element with a specific class when an element with a different or no class is below it.

For instance, let's use this code as an example.

< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
<button class="somebutton">Click Here</button>

< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
<image src="URL" />

Taking that example, I want to look at everything with the class name "my-paragraph", and when an element without the class of "my-paragraph" is below it, add another class to it which would be "nomargin" in this example.

This is what the final output might look like.

< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph nomargin">This is a sentence.</p>
<button class="somebutton">Click Here</button>

< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph">This is a sentence.</p>
< p class="my-paragraph nomargin">This is a sentence.</p>
<image src="URL" />

For the life of me, I can't work out how to code that up, and it's a problem that has absolutely been busting my brain for a few days and the imposter syndrome is real.

I feel like I want to start with a for loop, but I just can't get there on the logic side of it.

It would be great to be Vanilla JS if possible.

It might be easier to put the groupings of <p> tags in a containing div and then use css to style the container and take advantage of the css :last-of-type() selector to apply different styles to the last my-paragraph tag before a button or an image.

<div class="paragraph-container">
    <p class="my-paragraph">This is a sentence.</p>
    <p class="my-paragraph">This is a sentence.</p>
    <p class="my-paragraph nomargin">This is a sentence.</p>
</div>
<button class="somebutton">Click Here</button>

<div class="paragraph-container">
    <p class="my-paragraph">This is a sentence.</p>
    <p class="my-paragraph">This is a sentence.</p>
    <p class="my-paragraph nomargin">This is a sentence.</p>
</div>
<image src="URL" />

and then css something like this

.paragraph-container .my-paragraph:last-of-type() {
    margin: 0;
}

You may not even need the container, I always have to play around with the -of-type css selcectors a bit to get what I want

I think JDawwgy's answer is the best practice for this, but in case wrapping groups of paragraph tags into divs is not an option (like, maybe you're making a wysiwyg), here's a direct answer.

In vanilla JS, you can (a) get all paragraph tags, (b) loop through those paragraph tags, then (c) detect whether their next sibling is another <p> , then (d) apply a class if the next sibling is not a <p> .

const allParagraphs = document.querySelectorAll('p');

allParagraphs?.forEach((paragraphNode) => {
  const nextSibling = paragraphNode.nextSibling;

  if(nextSibling?.tagName.toLowerCase() !== 'p')
    paragraphNode.className += ' nomargin';
});
   

You can try this.

const children = [...document.getElementsByClassName("my-paragraph")];
children.forEach((child) => {
    if (!child.nextElementSibling.classList.contains("my-paragraph")) {
        child.classList.add('nomargin')
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM