Home > Software engineering >  JavaScript Show / Hide (toggle) function toggling classes but not working at the frontEnd
JavaScript Show / Hide (toggle) function toggling classes but not working at the frontEnd

Time:08-31

My goal is to be able to show / hide excerpt of the content. This is a wordpress site so posts are generated hence giving a button a unique ID is not an option. It must be working for all added posts in the future too.

The excerpt should be first hidden and shown once the button is clicked.

Current code adds and removes .excerpt class, however, the excerpt is not showing.

HTML

                <div ><?php the_post_thumbnail(); ?></div>
                <div >
                    <p ><?php the_category(', '); ?></p>
                    <h5 ><?php the_title(); ?></h5>
                    <p ><?php the_excerpt(); ?></p>
                    <button >Read More</button>
                </div>
                </div>

CSS

.excerpt   p {
  display: none;
}


.excerpt {
  display: block;
}

JS

const readMoreBtns = document.querySelectorAll('.read-more')

const showMoreHandler = (event) => {
const cardActiveParagraphs = document.querySelectorAll('.excerpt   p')
  
const cardBody = event.target.parentElement
const cardParagraph = cardBody.querySelector('.excerpt   p')
  console.log(cardParagraph)

cardActiveParagraphs.forEach((paragraph) => {
  paragraph.classList.toggle('excerpt')
})
  
}

readMoreBtns.forEach((button) => 
{
button.addEventListener('click', e => showMoreHandler(e));
});

CodePudding user response:

You can not toggle what is not in the dom. When you try to run this line:

const cardParagraph = cardBody.querySelector('.excerpt')
cardActiveParagraphs.forEach((paragraph) => {
      paragraph.classList.toggle('excerpt')
    })

You will only grab the elements that currently have the excerpt class, but not those that are turned off. A solution would be to add another class, just to grab them:

<p >the_category</p>
<h5 >the_title</h5>
<p >the_excerpt</p>

Then, in JS:

const cardActiveParagraphs = document.querySelectorAll('.some-flag-class');
cardActiveParagraphs.forEach((paragraph) => {
   paragraph.classList.toggle('excerpt')
})

This way, you will always grab both elements, regarding if they are on/off.

Also, you don't need to have a display: block and display: none class. Enough to have:

.excerpt {
  display: none;
}

and toggle on/off that class.

CodePudding user response:

I have solved the problem with the following js code:

const readMoreBtns = document.querySelectorAll('.read-more')

const showMoreHandler = (event) => {
const cardBody = event.target.parentElement
const cardActiveParagraphs = cardBody.querySelector('.excerpt   p')
  
    if(cardActiveParagraphs.style.display === 'none') {
        cardActiveParagraphs.style.display = 'block';
    }
    else {
        cardActiveParagraphs.style.display = 'none';
    }
}

readMoreBtns.forEach((button) => 
{
button.addEventListener('click', e => showMoreHandler(e));
});

  • Related