skip to Main Content

I’d like to create a website section where the user can click on a heading / secondary navigation buttons, and the corresponding content replaces the div underneath it. I got it working somewhat on my jsbin: https://jsbin.com/xibarokewa/edit/

When the page loads, the first div heading/link should be active and its respective content shown. The user should be able to navigate between divs 1 and 2, and the respective content and active heading should change according to that.

My issue is (apart from the really messy javascript): in order to change the active heading, the div1 heading has to trigger its javascript sequence by clicking on it, otherwise the active heading won’t change between div1 and div2. Do any of you know how I can achieve this so it works?

I’m sure there must be a guide or an article about doint this. I’ve scoured the internet for a solution, and in my desperation come up with this code – but this can definitely be improved. I’d love a simpler approach with less code. I’d prefer a solution without jQuery, as I want to learn Javasript first – as you can see, I’m pretty new to it.

HTML:

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="inline-grid">
    <div class="inline-grid-item">
      <p class="client-grid-link" id="div1-link" onclick="changeClient">div1</p>
    </div>
    <div class="inline-grid-item">
      <p class="client-grid-link" id="div2-link">div2</p>
    </div>
  </div>
  <div class="add-section" id="div1-content">
    <p class="add-paragraph">This is div 1.</p>
    </div>
    <div class="add-section" id="div2-content">
      <p class="add-paragraph">Div2 is different from div1</p>
    </div>
  </div>
</body>
</html>

CSS:

  display: grid;
  grid-template-columns: 1fr 1fr;
  margin: 0 auto;
}

.inline-grid-item {
  display: flex;
  align-items: center;
  justify-content: center;
}
  
.client-grid-link {
  border-bottom: 0.18rem solid transparent;
}

.client-grid-link#div1-link:hover {
  border-bottom: 0.18rem solid #970fc2;
  color: #970fc2;
  cursor: pointer;
}

.active.client-grid-link#div1-link {
  border-bottom: 0.18rem solid #970fc2;
}

.client-grid-link#div2-link:hover {
  border-bottom: 0.18rem solid #52b54b;
  color: #52b54b;
  cursor: pointer;
}

.active.client-grid-link#div2-link {
  border-bottom: 0.18rem solid #52b54b;
}

#div2-content {
  display: none;
}

JS:

var div2Link = document.getElementById("div2-link");
var div1Content = document.getElementById("div1-content");
var div2Content = document.getElementById("div2-content");

window.onload = function () {
  div1Link.classList.toggle("active");
}

div1Link.addEventListener("click", function () {
  if (div1Content.style.display === "none") {
    this.classList.toggle("active");
    div2Link.classList.remove("active");
    div1Content.style.display = "block";
    div2Content.style.display = "none";
  } else {
    div2Content.style.display = "none";
    div1Content.style.display = "block";
  }
});

div2Link.addEventListener("click", function () {
  if (div2Content.style.display === "none") {
    this.classList.toggle("active");
    div1Link.classList.remove("active");
    div1Content.style.display = "none";
    div2Content.style.display = "block";
  } else {
    div2Content.style.display = "block";
    div1Content.style.display = "none";
  }
});```

2

Answers


  1. You’re checking the style.display property of the content elements to determine their visibility. This property will only work if the styles are defined inline in the HTML, but you’ve defined the styles in your CSS. Instead, you can use the getComputedStyle method to check the computed styles of the elements.

    Fixed code:

    var div1Link = document.getElementById("div1-link");
    var div2Link = document.getElementById("div2-link");
    var div1Content = document.getElementById("div1-content");
    var div2Content = document.getElementById("div2-content");
    
    window.onload = function () {
      div1Link.classList.toggle("active");
    }
    
    div1Link.addEventListener("click", function () {
      if (getComputedStyle(div1Content).display === "none") {
        this.classList.toggle("active");
        div2Link.classList.remove("active");
        div1Content.style.display = "block";
        div2Content.style.display = "none";
      } else {
        div2Content.style.display = "none";
        div1Content.style.display = "block";
      }
    });
    
    div2Link.addEventListener("click", function () {
      if (getComputedStyle(div2Content).display === "none") {
        this.classList.toggle("active");
        div1Link.classList.remove("active");
        div1Content.style.display = "none";
        div2Content.style.display = "block";
      } else {
        div2Content.style.display = "block";
        div1Content.style.display = "none";
      }
    });
    
    Login or Signup to reply.
  2. Toggle the hidden attribute.

    hidden

    The hidden global attribute is an enumerated attribute indicating that the browser should not render the contents of the
    element. –MDN

    myButton.addEventListener("click", function () {
      myChildElement.toggleAttribute("hidden");
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search