skip to Main Content

i have a simple jquery script that works great:

$(function(){

    $("button").click(function(){ 
        $(this).parent().fadeOut(500, function() {
            $(this).next().fadeIn(500);
        });
    });
    
});
section {
    width: 300px;
    height: 250px;
    background-color: #2ac99e;
    margin: auto;
    display: flex;
    flex-direction: column;
}
button {
    display: block;
    margin-top: auto;
    margin-right: auto;
    margin-left: auto;
    font-size: 2em;
    padding: 10px;
    margin-bottom: 10px;
}
#p2,#p3,#p4 {display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

<section id="p1">
    <div>Content for  class "1" Goes Here</div>
    <button>Next</button>
</section>

<section id="p2">
    <div>Content for  class "2" Goes Here</div>
    <button>Next</button>
</section>

<section id="p3">
  <div>Content for  class "3" Goes Here</div>
  <button>Next</button>
</section>

<section id="p4">
  <div>Content for  class "4" Goes Here</div>
</section>

Based on that, I’m trying to create a simple JavaScript Only version, but struggle to get it working. Maybe you can tell me why i can’t get past 2nd box? Here’s code below:

document.querySelector("button").onclick = function() {func()};

function func () {
    let btn = document.querySelector("button").parentElement;
    let next = document.querySelector("button").parentElement.nextElementSibling;

    console.log(btn);

    btn.classList.add('hide');
    next.classList.remove('hide');
}
section {
    width: 300px;
    height: 250px;
    background-color: #2ac99e;
    margin: auto;
    display: flex;
    flex-direction: column;
}
button {
    display: block;
    margin-top: auto;
    margin-right: auto;
    margin-left: auto;
    font-size: 2em;
    padding: 10px;
    margin-bottom: 10px;
}
.hide {display:none;}
<section id="p1">
    <div>Content for  class "1" Goes Here</div>
    <button>Next</button>
</section>

<section id="p2" class="hide">
    <div>Content for  class "2" Goes Here</div>
    <button>Next</button>
</section>

<section id="p3" class="hide">
  <div>Content for  class "3" Goes Here</div>
  <button>Next</button>
</section>

<section id="p4" class="hide">
  <div>Content for  class "4" Goes Here</div>
</section>

basically I just need to hide existing element and show next element. I know i could create multiple functions with multiple buttons, but i want a reusable code where I could add any number of boxes later on without having to mess with the code each time.

2

Answers


  1. Try the following way:

    <!DOCTYPE html>
     <html lang="en">
     <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        .box {
            display: none;
        }
      </style>
      <title>Toggle Boxes</title>
    </head>
    <body>
    
    <div class="box" style="display: block;">Box 1 <button 
          onclick="toggleBoxes(this)">Next</button></div>
    <div class="box">Box 2 <button onclick="toggleBoxes(this)">Next</button>.</div>
    <div class="box">Box 3 <button onclick="toggleBoxes(this)">Next</button></div>
    
    <script>
        function toggleBoxes(button) {
            var currentBox = button.parentNode;
            var nextBox = currentBox.nextElementSibling;
    
            currentBox.style.display = 'none';
            nextBox.style.display = 'block';
        }
    </script>
    
    </body>
    </html>
    

    This code defines a function toggleBoxes that takes the button as a parameter, finds its parent div (current box), and the next sibling div (next box). It then sets the display property to control visibility.

    Note that I added a default style to hide all boxes initially.

    Login or Signup to reply.
  2. When you’re using querySelector it returns the first element that matches the selector (reference). That means you’re only adding the onclick handler to the first button in the code. You fix that by using the querySelectorAll method and iterating through all the elements to add the event handler. (reference).

    However, just that won’t work, for the same reason:

    This line let btn = document.querySelector("button").parentElement; selects always the first button, and for the second iteration, the first button is already hidden and it keeps showing the second div. You can check that by adding different ids to the buttons and checking the logs are always the first button.

    You’d need to make your event handler relative to the clicked button, and a good way to do that would be to add the eventListener with a callback that receives the event and use event.target to refer to the button that was actually clicked.

    document.querySelectorAll("button").forEach(e => {e.addEventListener('click', func)});
    
    function func (evt) {
    
        let btn = evt.target
        let next = btn.parentElement.nextElementSibling;
    
        console.log(btn);
    
        btn.parentElement.classList.add('hide');
        next.classList.remove('hide');
    }
    section {
        width: 300px;
        height: 250px;
        background-color: #2ac99e;
        margin: auto;
        display: flex;
        flex-direction: column;
    }
    button {
        display: block;
        margin-top: auto;
        margin-right: auto;
        margin-left: auto;
        font-size: 2em;
        padding: 10px;
        margin-bottom: 10px;
    }
    .hide {display:none;}
    <section id="p1">
        <div>Content for  class "1" Goes Here</div>
        <button>Next</button>
    </section>
    
    <section id="p2" class="hide">
        <div>Content for  class "2" Goes Here</div>
        <button>Next</button>
    </section>
    
    <section id="p3" class="hide">
      <div>Content for  class "3" Goes Here</div>
      <button>Next</button>
    </section>
    
    <section id="p4" class="hide">
      <div>Content for  class "4" Goes Here</div>
    </section>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search