最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Have read more button hide elements before being clicked - Stack Overflow

programmeradmin1浏览0评论

I have a basic understanding of html but I'll be honest I don't understand javascript at all and I copied this code from somewhere else. It works except everything under the 'read more' is visible on default and when you click the button it hides the elements. I want to know if there's a way to edit the code so when you open the page everything under the 'read more' is hidden and when you click it the elements appear.

Here's the code

<script>
function toggle(button){

    // this works because the button is immediately after the "moreDetails" element it pertains to
    let Text = button.previousElementSibling;

    // this would work if you move the button so it is not immediately after moreDetails, but still in the same parent div.
    //let Text = button.parentElement.querySelector(".moreDetails");
    
    if(Text.style.display == "block"){
        Text.style.display= "none";
    }
    else {
        Text.style.display = "none";
    }
}

const moreDetailses = document.querySelectorAll(".moreDetails");
for (let i = 0; i < moreDetailses.length; i++) {
  moreDetailses[i].style.display = "none";
}
</script>

I have a basic understanding of html but I'll be honest I don't understand javascript at all and I copied this code from somewhere else. It works except everything under the 'read more' is visible on default and when you click the button it hides the elements. I want to know if there's a way to edit the code so when you open the page everything under the 'read more' is hidden and when you click it the elements appear.

Here's the code

<script>
function toggle(button){

    // this works because the button is immediately after the "moreDetails" element it pertains to
    let Text = button.previousElementSibling;

    // this would work if you move the button so it is not immediately after moreDetails, but still in the same parent div.
    //let Text = button.parentElement.querySelector(".moreDetails");
    
    if(Text.style.display == "block"){
        Text.style.display= "none";
    }
    else {
        Text.style.display = "none";
    }
}

const moreDetailses = document.querySelectorAll(".moreDetails");
for (let i = 0; i < moreDetailses.length; i++) {
  moreDetailses[i].style.display = "none";
}
</script>
Share Improve this question asked Feb 6 at 6:55 froyofroyo 1 New contributor froyo is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 4
  • If you click edit and then the button marked [<>], you can create a minimal reproducible example. The simplest solution is to use CSS and have .moreDetails { display: none } and remove const moreDetailses = document.querySelectorAll(".moreDetails"); for (let i = 0; i < moreDetailses.length; i++) { moreDetailses[i].style.display = "none"; } – mplungjan Commented Feb 6 at 7:00
  • 1 Not clear at all. There is no “read more” in the code, probably, it is in HTML, so you need to show all relevant code, probably in a very simplified form. However, your approach is very inefficient. You need to read most of the material on JavaScript and understand at least the fundamentals. Working by examples without it would be a big waste of time. Your toggle is correct. For the loop, better use for (let element of array) .... – Sergey A Kryukov Commented Feb 6 at 7:01
  • Set the block that is to be hidden on load to be... hidden on load. ie change the source HTML itself: <div>more content<div> to <div style='display:none;'>more content</div> - then when you click the "more details" button it will show the hidden content. – fdomn-m Commented Feb 6 at 10:40
  • From a UX perspective, you don't want to show content then have javascript hide it just so the user can then show it by clicking something. The content should already be hidden as the page loads. – fdomn-m Commented Feb 6 at 10:41
Add a comment  | 

1 Answer 1

Reset to default 1

I will make a few assumptions until you show your HTML

The simplest solution is to use CSS and have

.moreDetails { display: none } 

which allows you to remove

const moreDetailses = document.querySelectorAll(".moreDetails"); 
for (let i = 0; i < moreDetailses.length; i++) {   
  moreDetailses[i].style.display = "none"; 
}

You do then need to change the script since initially JavaScript will return empty for the display since the style attribute is not set on the element in the html. I am using a ternary operator (? :) to simplify the if/else.

const toggle = (button) => {
  // this works because the button is immediately after the "moreDetails" element it pertains to
  let Text = button.previousElementSibling;
  Text.style.display = Text.style.display !== "block" ? 'block' : 'none'
};
.moreDetails {
  display: none;
}
<div id="textContainer">
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle" onclick="toggle(this)">More...</button>
  </div>
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle" onclick="toggle(this)">More...</button>
  </div>
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle" onclick="toggle(this)">More...</button>
  </div>

  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle" onclick="toggle(this)">More...</button>
  </div>
</div>

HOWEVER if you delegate from the container, let's assume it has id="textcontainer", and add the css .moreDetail.show { display: block } then the script becomes much simpler and you can remove the onclick="toggle(this)" from all buttons:

document.getElementById('textContainer').addEventListener('click', (e) => {
  const tgt = e.target.closest('button.toggle'); // did we click a button?
  if (!tgt) return; // No, bail out
  tgt.previousElementSibling.classList.toggle('show'); // classList.toggle does what is says
});
.moreDetails {
  display: none;
}

.moreDetails.show {
  display: block;
}
<div id="textContainer">
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle">More...</button>
  </div>
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle">More...</button>
  </div>
  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle">More...</button>
  </div>

  <div class="text">Here is some text
    <div class="moreDetails">And here are more details</div>
    <button class="toggle">More...</button>
  </div>
</div>

发布评论

评论列表(0)

  1. 暂无评论