Matta
Matta

Reputation: 23

Multiple JavaScript Buttons Simplified Into One Function

I have three buttons and three JS functions that toggle the display of three different divs. How can I simplify/condense my three JS functions into one function that connects each button to its corresponding content?

Example:

HTML Buttons

<button onclick="myFunction1()">Button 1</button>
<button onclick="myFunction2()">Button 2</button>
<button onclick="myFunction3()">Button 3</button>

HTML Content

<div id="ContentOne">This is Content One.</div>
<div id="ContentTwo">This is Content Two.</div>
<div id="ContentThree">This is Content Three.</div>

JavaScript

function myFunction1() {
    var x = document.getElementById("ContentOne");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}

function myFunction2() {
    var x = document.getElementById("ContentTwo");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}

function myFunction3() {
    var x = document.getElementById("ContentThree");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}

Upvotes: 2

Views: 1108

Answers (3)

JanS
JanS

Reputation: 2075

You can use a higher order function.

function generateFunction(elementId) {
    return function() {
        var x = document.getElementById(elementId);
        if (x.style.display === "none") {
            x.style.display = "block";
        } else {
            x.style.display = "none";
        }  
    }
}

var myFunction1 = generateFunction("ContentOne");
var myFunction2 = generateFunction("ContentTwo");
var myFunction3 = generateFunction("ContentThree");

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 206565

Inline JS is hard to maintain.
I'd use this code with just a line of CSS to hide elements,
and use JS simply to toggle that .hide class:

const toggleEl = e => document.getElementById(e.target.dataset.tog).classList.toggle("hide");

[...document.querySelectorAll("[data-tog]")].forEach( btn =>
    btn.addEventListener("click", toggleEl)
);
.hide { display: none;}
<button data-tog="ContentOne">Button 1</button>
<button data-tog="ContentTwo">Button 2</button>
<button data-tog="ContentThree">Button 3</button>

<div class="hide" id="ContentOne">This is Content One.</div>
<div class="hide" id="ContentTwo">This is Content Two.</div>
<div class="hide" id="ContentThree">This is Content Three.</div>

https://developer.mozilla.org/en-US/docs/Web/API/Element/classList

Here's a ES5 example if you prefer:

function toggleEl() {
  var id = this.getAttribute("data-tog");
  document.getElementById(id).classList.toggle("hide");
}

var buttons = document.querySelectorAll("[data-tog]");
[].forEach.call(buttons, function( btn ) {
  btn.addEventListener("click", toggleEl.bind(btn))
});
.hide { display: none;}
<button data-tog="ContentOne">Button 1</button>
<button data-tog="ContentTwo">Button 2</button>
<button data-tog="ContentThree">Button 3</button>

<div class="hide" id="ContentOne">This is Content One.</div>
<div class="hide" id="ContentTwo">This is Content Two.</div>
<div class="hide" id="ContentThree">This is Content Three.</div>

Upvotes: 2

Michael W. Czechowski
Michael W. Czechowski

Reputation: 3455

Add a parameter to the condensed function et violà!

function myFunction(id) {
  var x = document.getElementById(id);
  if (x.style.display === "none") {
    x.style.display = "block";
  } else {
    x.style.display = "none";
  }
}
<button onclick="myFunction('ContentOne')">Button 1</button>
<button onclick="myFunction('ContentTwo')">Button 2</button>
<button onclick="myFunction('ContentThree')">Button 3</button>

<div id="ContentOne">This is Content One.</div>
<div id="ContentTwo">This is Content Two.</div>
<div id="ContentThree">This is Content Three.</div>

Explanation

The only part that differs within the functions is the ID, so decouple the ID. The function does not need to know which element will be affected of the styling adaptions. So keep the function "dump".

Further learning: Anti-Patterns

If you are interested in improving your programming style, I suggest you take a look at some anti-pattern. For example, you demonstrated the antipattern of hard coding. It's not as untypical as you think.

Upvotes: 5

Related Questions