0

I got 3 buttons.

<button class="one"></button>
<button class="two"></button>
<button class="three"></button>

This is the JS part and my question is instead of writing 3 times, how can I add a function so that I can use it as many times as I need? Thanks for your help.

var openBtn = document.querySelector(".one");
var openBtnTwo = document.querySelector(".two");
var openBtnThree = document.querySelector(".three");
var hiddenBox = document.querySelector(".hidden-box");
       
       openBtn.onclick = function(){
    
        if(hiddenBox.style.display ==="none") {
    
            openBtn.innerText = "Close";
            hiddenBox.style.display = "block";
    
        }else {
    
            openBtn.innerText = "Learn More";
            hiddenBox.style.display = "none";
        }
    
       }

openBtnTwo.onclick = function(){
    
        if(hiddenBox.style.display ==="none") {
    
            openBtnTwo.innerText = "Close";
            hiddenBox.style.display = "block";
    
        }else {
    
            openBtnTwo.innerText = "Learn More";
            hiddenBox.style.display = "none";
        }
    
       }

openThree.onclick = function(){
    
        if(hiddenBox.style.display ==="none") {
    
            openThree.innerText = "Close";
            hiddenBox.style.display = "block";
    
        }else {
    
            openThree.innerText = "Learn More";
            hiddenBox.style.display = "none";
        }
    
       }

My question is instead of writing 3 times, how can I add a function so that I can use it as many times as I need? Thanks for your help.

nip
  • 1,609
  • 10
  • 20
Tom
  • 85
  • 7

1 Answers1

3

Move the shared code to a function, and replace specific code with generic code that can be applied to all elements. In this case, if you want to reference each button when clicked, you can use e.currentTarget.

function onClickHandler(e) {
    if (hiddenBox.style.display === "none") {
        e.currentTarget.innerText = "Close";
        hiddenBox.style.display = "block";
    } else {
        e.currentTarget.innerText = "Learn More";
        hiddenBox.style.display = "none";
    }
}

Then add a click event listener to the elements, like so:

openBtn.addEventListener('click', onClickHandler);
openBtnTwo.addEventListener('click', onClickHandler);
openThree.addEventListener('click', onClickHandler);

Edit: I've removed the .onclick method since this should not be used (ref), instead use .addEventListener. I've also replaced e.target by e.currentTarget as pointed out by @Roko C. Buljan.

nip
  • 1,609
  • 10
  • 20
  • 1
    (Nice answer.) I would not put your *"I'd also suggest"* as a *Post Scriptum*. There's not one single viable argument to use `on*` handlers on existing DOM elements. *Always* use `addEventListener` - unless, as I said, you're creating a brand new Element from in-memory. – Roko C. Buljan Jul 25 '21 at 17:51
  • 1
    Also, always think first `Event.currentTarget` - and only if you understand that currentTarget is not the desired Element, only than use `Event.target`. There's only one use case to use `Event.target` - and that's when traversing with `.closest()` to self-or-ancestor. – Roko C. Buljan Jul 25 '21 at 17:54
  • @RokoC.Buljan thanks for the input, I've editted my answer to reflect both points which I 100% agree. – nip Jul 25 '21 at 18:59