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

Time:05-31

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 >
    <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 >...</span>
        <span >- 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)" >Read more</button>
</div>

CodePudding user response:

One way to achieve this is to only have the event listener on the parent. And change your query selectors so you use the event.currentTarget instead of the event.target, so it behave 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  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 >...</span>
    <span >- 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 >Read more</button>
</div>

CodePudding user response:

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  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 >...</span>
      <span  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)" >Read more</button>
</div>

CodePudding user response:

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 @yousoumar. 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  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 >...</span>
    <span >- 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 >Read more</button>
</div>

  • Related