Katie Reynolds
Katie Reynolds

Reputation: 337

Javascript: Create Read More / Read Less Functionality for Multiple Blog Posts

New to JS. I am creating a blog from scratch, and trying to implement a Read More / Read Less button. I was able to get this working on one blog post, but it will be problematic obviously if I try to add the same classes to other blog posts, because then the function won't be sure which objects to act on.

Here is what I have now. You will find that clicking "Read More" / "Read Less" works fine on Blog Post 1, but when you click "Read More" on Blog Post 2, it will try to run the function on Blog Post 1:

function readMoreFunction() {
    var dots = document.getElementById("dots");
    var contentText = document.getElementById("content");
    var btnText = document.getElementById("buttonReadMore");
  
    if (dots.style.display === "none") {
      dots.style.display = "inline";
      btnText.innerHTML = "Read More";
      contentText.style.display = "none";
    } else {
      dots.style.display = "none";
      btnText.innerHTML = "Read Less";
      contentText.style.display = "inline";
    }
  }
#content {
  display: none;
}
<p><strong>Blog Title</strong></p>

<p>Here is an example of the short snippet I want to show by default. <span id="dots">...</span></p>
<span id="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction()" id="buttonReadMore">Read More</button>

<p><strong>Blog Title 2</strong></p>

<p>Here is another short snippet I want to show by default for the second blog post. <span id="dots">...</span></p>
<span id="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction()" id="buttonReadMore">Read More</button>

Basically, when the user clicks "Read More" right now, the ellipses disappear, the hidden content is now showing, and the button changes to "Read Less". When they click "Read Less", the ellipses will be inserted back into the shorter snippet portion, the full content is hidden again, and the button changes back to "Read More."

Short of giving new class names to every blog post and adding duplicate JS code for every single blog post with the new class names, how could I write a function to run independently for all of the different blog posts? Will I need to implement something like a "this" function, so it only happens for the local "this" object that is clicked?

I have tried to research how I would do this, but all I can find are very outdated 5+ year-old examples using jQuery, which I understand is obsolete now. Could you guys help point me in the right direction?

Upvotes: 0

Views: 1459

Answers (1)

Rahul R.
Rahul R.

Reputation: 6461

There could be multiple solutions, below is one with least modification to your code and using 'this':

function readMoreFunction(button) {
    var btnText = button;
    var contentText = button.previousElementSibling;
    var dots = contentText.previousElementSibling.children[0];
    
    if (dots.style.display === "none") {
      dots.style.display = "inline";
      btnText.innerHTML = "Read More";
      contentText.style.display = "none";
    } else {
      dots.style.display = "none";
      btnText.innerHTML = "Read Less";
      contentText.style.display = "inline";
    }
  }
.content{
  display: none;
}
<p><strong>Blog Title</strong></p>

<p>Here is an example of the short snippet I want to show by default. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction(this)" class="buttonReadMore">Read More</button>

<p><strong>Blog Title 2</strong></p>

<p>Here is another short snippet I want to show by default for the second blog post. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction(this)" class="buttonReadMore">Read More</button>

Remember, we cannot use same id for 2 or more element, it should be unique for an element on entire DOM.

Instead of passing this, you could also pass index from you onclick call i.e. readMoreFunction(0),readMoreFunction(1) which will work for static html cases. previousSibling property.

Upvotes: 1

Related Questions