Utilizing Vanilla JavaScript to Insert a Class When a Distinct Class Exists Within an Element

My goal is to dynamically add a class to specific elements based on the presence of another class in elements below them.

Consider the following code snippet:

< 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" />

I want to add a class "nomargin" to elements with the class "my-paragraph" if an element without that class is directly below it.

After implementing this logic, the final output would resemble the following:

< 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" />

I've been struggling to come up with a solution for this problem using Vanilla JavaScript, and it's been challenging me for a few days now, causing some imposter syndrome feelings.

I believe starting with a for loop could be a good approach, but I'm stuck on the implementation logic. Any guidance or help would be greatly appreciated.

Answer №1

Give this solution a shot.

let paragraphs = [...document.querySelectorAll('.my-paragraph')];
paragraphs.forEach((paragraph) => {
    if (!paragraph.nextElementSibling.classList.contains('my-paragraph')) {
        paragraph.classList.add('nomargin');
    }
});

Answer №2

To simplify the organization of <p> tags, consider placing them within a div and utilizing css for styling. By using the css :last-of-type() selector, you can 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" />

You can implement css similar to the following:

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

It's possible that you may not need the container. Experimenting with the -of-type css selectors can help achieve the desired result.

Answer №3

While JDawwgy's solution is a great approach, there are alternative methods to consider for situations where grouping paragraph tags into divs is not feasible, such as when using a wysiwyg editor.

For instance, in plain JavaScript, you could (a) select all paragraph tags, (b) iterate through them, (c) check if the next sibling is another <p>, and (d) add 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';
});
   

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: The variable 'err' is undefined in the mongoose mongodb code

Every time I try to execute this code, an error pops up stating that err is undefined Below is the code snippet causing the issue: app.post('/tinder/cards', (req, res) => { const dbCard = req.body; Cards.create(dbCard, (err, data) => { ...

What is the best way to extend the width of an element within a Bootstrap column beyond the column itself?

Apologies for any language errors, but I have a query regarding Bootstrap. I am currently working on making a website responsive and I have a row with 4 columns set up like this: The "seeMore" div is initially hidden and on clicking the boxToggle element ...

I'm wondering why my .focus() function is causing the cursor to move to the start of my contenteditable div?

I am currently developing a website for writing books, primarily using php. I have implemented a jQuery function that, upon clicking the "New Chapter" button, triggers an AJAX function along with various other JS/jQuery events. One of these events is inten ...

jQuery Load - Oops! There seems to be a syntax error: Unexpected token <

Error: Uncaught SyntaxError: Unexpected token < I encountered the error message mentioned above while trying to execute a jQuery load function: $('#footer').load(UrlOfFooterContent); The variable UrlOfFooterContent holds the URL of an MVC c ...

Validation does not occur when the submit button has an ng-click event attached to it

This is the form I created: <form action="" ng-controller="forgotCtrl as forgot" name="forgotForm"> <div class="form-group row"> <label for="email" class="col-sm-2 form-control-label">Email address</label> ...

What is the best way to sort through data retrieved by a server component in a NextJS 13 AppDir?

I've hit a roadblock trying to integrate a search bar that filters server-fetched data in my project using NextJS 13 and AppDir. Despite numerous attempts, I can't seem to get it right. It feels like there's something crucial I'm overlo ...

Finding the nearest span element with a selector in styled components

Currently experimenting with integrating Styled Components to target the nearest span element. <label> <span className="">Password</span> <input type="password" id="passwordInput" /> </label> ...

Animated the height of a rectangle during initial loading and when the mouse hovers over or leaves

Being new to Vue.js, I am looking to create a simple animation on component load for the first time. You can find my initial code here: <template> <div id="app"> <div class="rect" /> </div> </template ...

Yeoman - Storing global settings efficiently

I have recently developed a Yeoman generator and am now looking to incorporate prompts for certain global configurations. My goal is to have the generator prompt users for their GitHub username and token during the initial run, and then somehow store this ...

Navigating between pages using the ExpressJS and Angular 1 routing system

Can someone help me troubleshoot an issue I'm having with my Express API and Angular front-end? Whenever I try to access the /about route, it keeps defaulting back to index.html and displaying a 404 error message. Can you take a look at my code and pi ...

remove leading spaces in JavaScript after retrieving data from database

Hey there, I need help with trimming the leading spaces using JavaScript when the value is fetched from a database. I am using JSP tags to retrieve the value and load it into an input field. The issue I'm facing is that if there are any spaces at the ...

Erase a chat for only one user within a messaging application

Currently, I am in the process of building a chat application using nodejs and mongodb. In order to structure my database properly, I have created two models: conversation and messages. Message.js conversationId: { //conversationID }, body: ...

Transform the jQuery UI colorpicker slider into a jQuery Mobile compatible version

I'm not very familiar with JavaScript programming, so I'm feeling a bit lost while trying to understand the code in the jQuery Mobile library (the lack of comments doesn't help). I managed to create a colorpicker slider using jQuery UI, you ...

The NgModel function within *ngFor is executing more times than necessary during initialization

Displayed on screen are a list of tutorials with check boxes next to each tutorial's states. These tutorials and states are pulled from the database, each tutorial containing a name and an array of associated states. Here is the HTML code: <div c ...

Previewing posts on a single page can be done by following a few

Hello there! I have written some code in React.js I am trying to display my blog posts on a single page when the user clicks on the "read more" button. I am fetching this data from a news API and I want to show each post based on its specific ID, which i ...

Angular Material Rotate Ink Bar to Vertical Orientation

After wanting to change the orientation of Angular Material's Tab Component to vertical, I visited this page (Tabs) and experimented with the CSS. By making the necessary adjustments, I successfully displayed the tabs vertically using the following CS ...

Text in SVG vanishes when label size increases

I've been exploring Morris.js for creating charts, which relies on SVG to generate graphs. I've shared a JSbin setup here: JSbin example One challenge with Morris.js is the X-Axis labels disappearing when they are too large. Adjusting the size o ...

Verification of javascript for an unpredictable image generator script

When running the W3C Validation tool, an error is returned stating 'img not acceptable here.' Any suggestions on how to resolve this issue? <script type="text/javascript" language="JavaScript"> NumberOfImagesToRotate = 9; FirstPart = &ap ...

Having trouble with loading image textures in three.js

Here is the code snippet I am using: var scene = new THREE.Scene(); // adding a camera var camera = new THREE.PerspectiveCamera(fov,window.innerWidth/window.innerHeight, 1, 2000); //camera.target = new THREE.Vector3(0, 0, 0); // setting up the renderer ...

Navigate to a different page using Angular2 routing

Looking for guidance on using redirect in the new Angular 2 router. Specifically interested in examples similar to 'redirectTo' from the beta version. Any demos on 'plnkr.co' would be greatly appreciated! ...