1

If you look at my HTML and CSS, I have a fairly straight forward problem, but being a JS noob, I can't think of a straight forward answer.

I have a bunch of buttons, followed by a bunch of hidden divs. The hidden divs are absolutely positioned on top of the buttons, with opacity:0. I want each button to toggle the .show class on the corresponding div, to show it.

Is there an elegant way to do this with javascript without repeating the code? I'd prefer not to use jQuery tbh.

Thanks a lot.

*, :after, :before {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box
    }
        .wrapper {
            display: grid;
            grid-template-columns: 1fr;
            padding: 8px;
            border-radius: 6px;
            position: relative;
        }
        .btn {
            padding: 10px;
            border-radius: 6px;
            margin: 8px;
            background-color: #ddd;
        }
        a.btn {
            color: blue;
            font-weight: bold;
            text-decoration: none;
            font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
            transition: 0.3s;
        }
        a.btn:hover {
            background-color: #ccc;
            transition: 0.3s;
        }
        .overlay {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            padding: 10px;
            opacity: 0;
            visibility: hidden;
        }
        .show {opacity: 1; visibility: visible;}
        #panel1 {background-color: coral;}
        #panel2 {background-color: cornflowerblue;}
        #panel3 {background-color: darkgoldenrod;}
        #panel4 {background-color: darkseagreen;}
        #panel5 {background-color: deeppink;}
<div class="wrapper">
        <a id="btn1" href="#" class="btn">
            <span>Button one</span>
        </a>
        <a id="btn2" href="#" class="btn">
            <span>Button two</span>
        </a>
        <a id="btn3" href="#" class="btn">
            <span>Button three</span>
        </a>
        <a id="btn4" href="#" class="btn">
            <span>Button four</span>
        </a>
        <a id="btn5" href="#" class="btn">
            <span>Button five</span>
        </a>

        <div id="panel1" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel2" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel3" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel4" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel5" class="overlay">
            <a href="#">Close</a>
        </div>
    </div>
blurfus
  • 13,485
  • 8
  • 55
  • 61
Phil
  • 77
  • 3
  • 1
    Add `data-toggle="#idHere"` to any desired button or other element. On click get that ID element and use `thatElement.classList.toggle("is-hidden")` I'll leave the rest of the solution to your discovery. – Roko C. Buljan Jul 21 '20 at 21:03
  • Does this answer your question? [JavaScript click event listener on class](https://stackoverflow.com/questions/19655189/javascript-click-event-listener-on-class) – blurfus Jul 21 '20 at 21:10

1 Answers1

0

Get all needed elements by their class and assign event listeners. Take a look at comments on every block of code to know how it works:

// Just one function for all buttons
function btnClick(e) {
  // Get link element from clicked button
  let btn = e.target.closest('a');
  // Get number from id
  let num = btn.id.replace('btn', '');
  // Show the panel
  document.querySelector('#panel' + num).classList.toggle('show');
}

function panelClose(e) {
  e.target.closest('div').classList.toggle('show');
}

// Get all buttons
let btns = document.querySelectorAll('.btn');
btns.forEach(btn => btn.addEventListener('click', btnClick));

// Get all closing links
let cls = document.querySelectorAll('.overlay a');
cls.forEach(cl => cl.addEventListener('click', panelClose));
*, :after, :before {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box
    }
        .wrapper {
            display: grid;
            grid-template-columns: 1fr;
            padding: 8px;
            border-radius: 6px;
            position: relative;
        }
        .btn {
            padding: 10px;
            border-radius: 6px;
            margin: 8px;
            background-color: #ddd;
        }
        a.btn {
            color: blue;
            font-weight: bold;
            text-decoration: none;
            font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
            transition: 0.3s;
        }
        a.btn:hover {
            background-color: #ccc;
            transition: 0.3s;
        }
        .overlay {
            position: absolute;
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            padding: 10px;
            opacity: 0;
            visibility: hidden;
        }
        .show {opacity: 1; visibility: visible;}
        #panel1 {background-color: coral;}
        #panel2 {background-color: cornflowerblue;}
        #panel3 {background-color: darkgoldenrod;}
        #panel4 {background-color: darkseagreen;}
        #panel5 {background-color: deeppink;}
<div class="wrapper">
        <a id="btn1" href="#" class="btn">
            <span>Button one</span>
        </a>
        <a id="btn2" href="#" class="btn">
            <span>Button two</span>
        </a>
        <a id="btn3" href="#" class="btn">
            <span>Button three</span>
        </a>
        <a id="btn4" href="#" class="btn">
            <span>Button four</span>
        </a>
        <a id="btn5" href="#" class="btn">
            <span>Button five</span>
        </a>

        <div id="panel1" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel2" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel3" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel4" class="overlay">
            <a href="#">Close</a>
        </div>
        <div id="panel5" class="overlay">
            <a href="#">Close</a>
        </div>
    </div>
Triby
  • 1,739
  • 1
  • 16
  • 18
  • This is great. I really appreciate the comments to help me understand how it works. Thanks a lot! – Phil Jul 21 '20 at 23:07