简体   繁体   中英

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>

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>

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>

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 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM