GoMega54
GoMega54

Reputation: 148

Separate counters using closure

Given the following code, how would you make each button add 1 to its respective counter. Currently when a button is pressed it adds 1 to its counter, but when the other button is pressed it adds the sum of the other counter plus 1. I know this can be done by creating another add variable, but is it possible to do this without creating another counter function?

<button type="button" onclick="myFunction()">Count!</button>
<button type="button" onclick="myFunction2()">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>
<script>
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

function myFunction(){
    document.getElementById("demo").innerHTML = add();
}

function myFunction2(){
    document.getElementById("demo2").innerHTML = add();
}
</script>

Upvotes: 0

Views: 220

Answers (4)

Dhananjaya Kuppu
Dhananjaya Kuppu

Reputation: 1322

You may also try this :

function counter(start) {
    return function increment(){
        start += 1;
        return start;
    }
}

function onButtonClick(sourceElemId, counterFunc){
    document.getElementById(sourceElemId).innerHTML = counterFunc();
}

In HTML:

<button type="button" 
       onclick="onButtonClick('demo', counter(0))">Count!
 </button>
<button type="button" 
        onclick="onButtonClick('demo2', counter(0))">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>

Upvotes: 1

Jaromanda X
Jaromanda X

Reputation: 1

You can do the following, note the added id to the button to make things simple

<button type="button" id="btn1">Count!</button>
<button type="button" id="btn2">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>
<script>
function counter(b, p) {
  var button = document.getElementById(b);
  var para = document.getElementById(p);
  var value = 0;
  button.addEventListener('click', function() {
    para.innerHTML = value += 1;
  });
}
counter('btn1', 'demo');
counter('btn2', 'demo2');
</script>

Each call to counter creates a closure for the click event to update the correct <p>

Even simpler, you don't need to create a var to hold the value as the value is held in the element itself

<button type="button" id="btn1">Count!</button>
<button type="button" id="btn2">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>
<script>
function counter(b, p) {
  var para = document.getElementById(p);
  document.getElementById(b).addEventListener('click', function() {
    para.innerHTML = parseInt(para.innerHTML) + 1;
  });
}
counter('btn1', 'demo');
counter('btn2', 'demo2');
</script>

Upvotes: 1

larz
larz

Reputation: 5766

var counter1 = 0;
var counter2 = 0;
var add = function (count) {
    return count += 1;
};

function myFunction(){
    counter1 = add(counter1)
    document.getElementById("demo").innerHTML = counter1;
}

function myFunction2(){
    counter2 = add(counter2)
    document.getElementById("demo2").innerHTML = counter2;
}
<button type="button" onclick="myFunction()">Count!</button>
<button type="button" onclick="myFunction2()">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>

You were redefining counter to be 0 every time you called add. In addition, since you want two different counters, you need two different variables to keep track of each. And honestly you could probably eliminate the add function and just add to each counter within its specific function with counterX = counterX++ instead of counterX = add(counterX)

Upvotes: 0

obataku
obataku

Reputation: 29646

Consider creating a separate counter as follows without having to duplicate the add logic.

<button type="button" onclick="count1()">Count!</button>
<button type="button" onclick="count2()">Count!</button>
<p id="demo">0</p>
<p id="demo2">0</p>
<script>
  function createCounter() {
    var counter = 0;
    return function () { return ++counter; }
  }

  var counter1 = createCounter();
  var counter2 = createCounter();

  function count1() {
    document.getElementById("demo").innerHTML = counter1();
  }

  function count2() {
    document.getElementById("demo2").innerHTML = counter2();
  }
</script>

Upvotes: 1

Related Questions