1

I'm trying to make read more button using javascript substring but my code is not working, I can hide text but, can not show more on click

<p class="pr">More than 200</p>
<button class="btn">Read more</button>
<script>
  var pr = document.querySelectorAll('.pr');
  var btn = document.querySelectorAll('.btn');

  for (var i = 0; i < pr.length; i++) {
    if(pr[i].innerHTML.length >= 200){
      var showLess = pr[i].innerHTML.substring(0, 200);
      pr[i].innerHTML = showLess;
    }
    btn.addEventListener('click', showMore);

    function showMore(){
      var showMore = pr[i].innerHTML.substring(0, );
      pr[i].innerHTML = showMore;
    }
  }
</script>
1
  • When you change .innerHTML, it gets permanently changed. Try storing the original text in js or some hidden element and use that to manipulate .innerHTML. Commented Aug 30, 2019 at 11:00

3 Answers 3

1

Firstly, you should store the text inside a variable, because if you then shorten it, javascript doesn't remember the first text:

var text = pr[i].textContent; // make this the first thing in the for loop

Then, instead of referring to pr[i].innerHTML.substring use text.substring (only when getting the value, not when setting it).

I hope this will work, haven't tested it (writing on my phone).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for simple explain :)
This probably will not work for multiple texts though, because with each iteration of the loop, the variables change and it would only work for the last element.
0

You are overriding the innerHTML with the short string so you need to hold the original value in a variable. In my snippet I save the original string in the more variable.

Furthermore the document.querySelectorAll('.btn'); returns a NodeList object on which you cannot attach an event listener directly, you need to iterate through each node and add it to those.

In your code you were getting a TypeError on the addEventListener call so the callback was not attached to the click event.

Lastly, do not use the innerHTML use textContent as innerHTML is a costly operation. Read more here .

Element.innerHTML returns HTML, as its name indicates. Sometimes people use innerHTML to retrieve or write text inside an element, but textContent has better performance because its value is not parsed as HTML. Moreover, using textContent can prevent XSS attacks.

var pr = document.querySelectorAll('.pr');
var btn = document.querySelectorAll('.btn');

for(let i =0; i<pr.length; i++){
  let more = pr[i].textContent;
  if(more.length >= 5){
    let showLess = more.substring(0, 5);
    pr[i].textContent = showLess;
  }
  btn.forEach(b => b.addEventListener('click', () => {
     console.log(more);
     pr[i].textContent = more;
  }));
  
}
  
<p class="pr">More than 200</p>
<button class="btn">Read more</button>

Comments

0

A simpler version using Id instead of class.

let pr = document.getElementById('pr');
let btn = document.getElementById('btn');
let actualText = pr.innerHTML; 
if(pr.innerHTML.length >= 200){
  pr.innerHTML =  pr.innerHTML.substring(0, 200);
  btn.addEventListener('click', () => { pr.innerHTML = actualText;});
}
<p id="pr">This is basic test content which length is More than 200, This is basic test content which length is More than 200, This is basic test content which length is More than 200, This is basic test content which length is More than 200, This is basic test content which length is More than 200, This is basic test content which length is More than 200, This is basic test content which length is More than 200</p>
<button id="btn">Read more</button>

And yes you need to store your original text content before updating the innerHTML of the element.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.