user4774980
user4774980

Reputation:

Appropriate way to toggle in Javascript/jQuery without using global variables?

Usually when I code a toggle function for example toggling between 2 background colors, I use a global variable as a flag. For example like this -

var flag = true;
function change()
{
  if(flag)
    {
      document.getElementById("box").style.backgroundColor = "blue";
      flag = false;
    }
  else
    {
      document.getElementById("box").style.backgroundColor = "red";
      flag = true;
    }
}
#box
{
  width:100px;
  height:100px;
  background-color:red;
}
<h3>Click the box to toggle</h1>
<div id="box" onclick="change()"></div>

But when I code multiple functions to toggle various properties, the number of global variables increases and as stated by these articles-
Article #1
Article #2
Article #3
Global variables must be avoided. So my question is, what is the other way to write a simple function like toggle?

Upvotes: 3

Views: 1814

Answers (5)

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

jQuery's toggleClass method exists for precisely this purpose:

$('.box').click(function() {
  $(this).toggleClass('blue');
});
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  display: inline-block;
  margin: 10px;
}

.box.blue {
  background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Click the box to toggle</h3>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

If you need to toggle between more than two classes, you can check hasClass, then use addClass and removeClass:

$('.box').click(function() {
  if($(this).hasClass('blue')) {
    $(this).removeClass('blue');
    $(this).addClass('green');
  }
  else if($(this).hasClass('green')) {
    $(this).removeClass('green');
  }
  else {
    $(this).addClass('blue');
  }
});
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  display: inline-block;
  margin: 10px;
}

.box.blue {
  background-color: blue;
}

.box.green {
  background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Click the box</h3>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

If you want to attach a non-CSS property to an element, use data:

$('button').click(function() {
  var clicks= $(this).data('clicks') || 1;
  if(clicks>=3) {
    $(this).html('You clicked me thrice!');
  }
  else {
    $(this).data('clicks', clicks+1);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me three times</button>

Upvotes: 0

Hoyen
Hoyen

Reputation: 2519

You could create a Module object for the page/site like so:

HTML

<h3>Click the box to toggle</h3>
<div id="box" onclick="MyModule.change(this)">Change Color</div>

JavaScript

var MyModule = (function(){
    var boxFlag = true;
    return{
        change: function(ele){
            if(boxFlag){
                 ele.style.backgroundColor = "blue";
            }
            else{
                ele.style.backgroundColor = "red";
            }
            boxFlag = !boxFlag;
        }
    }
})();

JSFiddle: http://jsfiddle.net/sbznrhgy/1/

Upvotes: 0

Chad Watkins
Chad Watkins

Reputation: 561

You can use an immediately invoked function expression (IIFE) to avoid polluting the global scope with variable names. An example of an anonymous IIFE is as follows:

(function(){
var flag = true;
function change()
{
  if(flag)
  {
      document.getElementById("box").style.backgroundColor = "blue";
      flag = false;
  }
  else
    {
      document.getElementById("box").style.backgroundColor = "red";
      flag = true;
    }
}

}());

by wrapping your code in a function you have created another level of scope and are preserving the global space. Here is an article on it but you can find lots of articles if you just type in a search engine 'IIFE'

Upvotes: 3

Wim Mostmans
Wim Mostmans

Reputation: 3601

You can do this by using addEventListener to bind to the click event in combination with a self-executing anonymous function.

(function(){
   var flag = true;
   document.getElementById('box').addEventListener('click', function() {
       this.style.backgroundColor = flag ? "blue" : "red";
       flag = !flag;

   });
})();
#box
{
  width:100px;
  height:100px;
  background-color:red;
}
<h3>Click the box to toggle</h1>
<div id="box"></div>

Upvotes: 3

brso05
brso05

Reputation: 13232

You can check the background color property then do the opposite like this:

 if(document.getElementById("box").style.backgroundColor == "red")
 {
      document.getElementById("box").style.backgroundColor = "blue";
 }
 else
 {
      document.getElementById("box").style.backgroundColor = "red";
 }

If you have more than 2 options just add elseif statements...

Upvotes: 0

Related Questions