kebabdude
kebabdude

Reputation: 21

Show more of div's content text when inner button or the div itself is clicked

I have this code and I wonder if I can show the rest of text when clicking on the div area instead of only the button and if its possible to connect them together.

function ReadMore(event) {
  var dots = event.target.previousElementSibling.querySelector(".dots");
  var moreText = event.target.previousElementSibling.querySelector(".more");
  var btnText = event.target;

  if (dots.style.display === "none") {
    dots.style.display = "inline";
    btnText.innerHTML = "Read more";
    moreText.style.display = "none";
  } else {
    dots.style.display = "none";
    btnText.innerHTML = "Read less";
    moreText.style.display = "inline";
  }
}
.more { 
  display: none; 
 }
<div class="glide__slide">
    <h3>Inka B.</h3>
    <p>Nádherné místo u lesa, ubytování v krásných, čistých zrenovovaných prostorách. Společná kuchyň velká se 3 linkami, 2 sporáky, 2 mikrovlnkami... když je více lidí, stále se dá vařit. A vedlejší jídelna pojme přes 20 lidí
        <span class="dots">...</span>
        <span class="more">- ideální i na rodinnou oslavu. Postele pohodlné, pokoje útulné...a ten výhled z terasy! Na
            všem se dalo domluvit...zkrátka, vracíme se zpět! Cítili jsme se tu opravdu vítání. Děkujeme!</span>
    </p>
    <button onclick="ReadMore(event)" class="myBtn">Read more</button>
</div>

Upvotes: 2

Views: 896

Answers (3)

Maik Lowrey
Maik Lowrey

Reputation: 17556

update use currentTarget and assign the click event on the entire div. https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget

My first answer i recommended to use parentNode to fetch the div. https://developer.mozilla.org/en/docs/Web/API/Node/parentNode . But this will trough a error if you will click on the hidden span. Thanks to @YoussoufOumar. He pointed out ;-)

function ReadMore(event) {  
  const div = event.currentTarget; 
  var dots = div.querySelector(".dots");  
  var moreText = div.querySelector(".more");
  var btnText = div.querySelector("button");
    
  if (dots.style.display === "none") {
    dots.style.display = "inline";
    btnText.innerHTML = "Read more";
    moreText.style.display = "none";
  } else {
    dots.style.display = "none";
    btnText.innerHTML = "Read less";
    moreText.style.display = "inline";
  }
  }
.more {
    display: none;
}
<div class="glide__slide" onclick="ReadMore(event)">
  <h3>Inka B.</h3>
  <p>Nádherné místo u lesa, ubytování v krásných, čistých 
    zrenovovaných prostorách. Společná kuchyň velká se 3 linkami, 
    2 sporáky, 2 mikrovlnkami... když je více lidí, stále se dá vařit. 
    A vedlejší jídelna pojme přes 20 lidí
    <span class="dots">...</span>
    <span class="more">- ideální i na rodinnou oslavu. Postele pohodlné, pokoje útulné...a ten výhled z terasy! Na všem se dalo domluvit...zkrátka, vracíme se zpět! Cítili jsme se tu opravdu vítání. Děkujeme!</span></p>
  <button class="myBtn">Read more</button>
</div>

Upvotes: 0

Youssouf Oumar
Youssouf Oumar

Reputation: 45883

One way to achieve this is to only have the event listener on the parent. And to change your query selectors so you use the event.currentTarget instead of the event.target, so it behaves identically no matter where the event is coming from in the div.

function ReadMore(event) {
  var dots = event.currentTarget.querySelector(".dots");
  var moreText = event.currentTarget.querySelector(".more");
  var btnText = event.currentTarget.querySelector("button");

  if (dots.style.display === "none") {
    dots.style.display = "inline";
    btnText.innerHTML = "Read more";
    moreText.style.display = "none";
  } else {
    dots.style.display = "none";
    btnText.innerHTML = "Read less";
    moreText.style.display = "inline";
  }
}
.more {
  display: none;
}
<div class="glide__slide" onclick="ReadMore(event)">
  <h3>Inka B.</h3>
  <p>Nádherné místo u lesa, ubytování v krásných, čistých
    zrenovovaných prostorách. Společná kuchyň velká se 3 linkami,
    2 sporáky, 2 mikrovlnkami... když je více lidí, stále se dá vařit.
    A vedlejší jídelna pojme přes 20 lidí
    <span class="dots">...</span>
    <span class="more">- ideální i na rodinnou oslavu. Postele pohodlné, pokoje útulné...a ten výhled z terasy! Na všem se dalo domluvit...zkrátka, vracíme se zpět! Cítili jsme se tu opravdu vítání. Děkujeme!</span>
  </p>
  <button class="myBtn">Read more</button>
</div>

Upvotes: 3

Diego D
Diego D

Reputation: 8163

The trick here was using event.stopPropagation() when the event was fired by the button. That's because the event will bubble to the parent when the button gets clicked (because both the element have the handlers registered for that event) and it would trigger the handler twice otherwise.

I'll be more clear. You have both the div container and the button listening to the click event. If the click occurs on the button, it will first cause the handler listening for the button to trigger. After that, since the button is nested inside the div and that div has an handler listening for the click event, also that one will be triggered (because the event is said to bubble up https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#event_bubbling_and_capture). To avoid the handler to be called twice for the same event, I'm checking if the element firing the event is the button and in that case it will stop the propagation (the bubbling up to the parent).

function ReadMore(event) {    

    //this is a brutal way to get the html elements based on which element fired the event
    if(event.target.classList.contains('myBtn')){      
      btn = event.currentTarget;
      dots = btn.parentElement.querySelector('.dots');
      more = btn.parentElement.querySelector('.more');      
    }else{    
      btn = event.currentTarget.querySelector('.myBtn');
      dots = event.currentTarget.querySelector('.dots');
      more = event.currentTarget.querySelector('.more');      
    }
    
    if (dots.style.display === "none") {
      dots.style.display = "inline";
      btn.innerHTML = "Read more";
      more.style.display = "none";
    } else {          
      dots.style.display = "none";
      btn.innerHTML = "Read less";
      more.style.display = "inline";
    }
    
    if(event.target.classList.contains('myBtn'))
      window.event.stopPropagation();
    
  }
button.myBtn{
  cursor: pointer;
}
<div class="glide__slide" onclick="ReadMore(event)">
  <h3>Inka B.</h3>
  <p>Nádherné místo u lesa, ubytování v krásných, čistých 
      zrenovovaných prostorách. Společná kuchyň velká se 3 linkami, 
      2 sporáky, 2 mikrovlnkami... když je více lidí, stále se dá vařit. 
      A vedlejší jídelna pojme přes 20 lidí
      <span class="dots">...</span>
      <span class="more" style="display:none;">- ideální i na rodinnou oslavu. Postele pohodlné, pokoje útulné...a ten výhled z terasy! Na všem se dalo domluvit...zkrátka, vracíme se zpět! Cítili jsme se tu opravdu vítání. Děkujeme!
      </span>
  </p>
  <button onclick="ReadMore(event)" class="myBtn">Read more</button>
</div>

Upvotes: 0

Related Questions