I have a container with text that I want to show a read more/read less function that when clicked, displays or hides text. The problem is, I have about 10 of these containers on the same page and when I click a read more in one of the containers it affects every container on the page. I need the read more / read less function to only happen on the container where I click.
jQuery(document).ready(function($) {
var productDescription = $('.summary'),
productReadMore = $('.description-read-more'),
currentHeight = productDescription.height(),
autoHeight = productDescription.css('height', 'auto').height(),
showMoreText = 'Read More',
showLessText = 'Read Less';
productDescription.css('height', currentHeight);
productReadMore.click(function() {
if ($(this).hasClass('active')) {
$(this).removeClass('active');
productDescription.removeClass('active');
productDescription.height(currentHeight).animate({
height: currentHeight
}, 0);
productReadMore.find('.text_more').html(showMoreText);
} else {
$(this).addClass('active');
productDescription.addClass('active');
productDescription.height(currentHeight).animate({
height: autoHeight
}, 0);
productReadMore.find('.text_more').html(showLessText);
}
});
});
<div class="summary">
<p><strong>Description:</strong></p>
<p>initial content</p>
<p>more content</p>
</div>
<div class="description-read-more"><span class="text_more">Read More</span></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
3
Answers
Use event delegation. Add a listener to the
document
for which the handler only works if the event target (the element that was clicked on) has aread-more
class.I would then group the section that needs to be displayed within the section that’s triggering its opening/closing. From there grab the
summary
element of the clicked button usingclosest
, find the section with thetext-more
class, and thentoggle
it.If you don’t want to group the markup together you can use data attributes to indicate which section should be toggled instead.
One idea, without using JavaScript, would be to animate to auto height using CSS
grid
and use a checkbox (or radio) input for the toggling.In this example I’m using the
:has()
, but to support Firefox (2023. ATM)you can place the input in the parent wrapper and reference sibling elements using
~
.In jQuery when you make a search of the kind of
$(someselector)
then all the items matching that selector apply. Hence, for example,productReadMore
is defined asand that applies for all elements having this class. Which is good when you call the
.click()
function, because it attaches aclick
event for all elements having this class. However, inside the function you need to differentiate and use$(this)
rather thanproductReadMore
to identify the item to change rather than change all items.