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>
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?
- 1 You should put global variables in a namespace for that project. So, if you have a lot of variables you're using, instead of: var x, y, z; do: var MyVars = {x:xvar, y:yvar, z:zvar} that way you can keep global variables but they're organized under a namespace. And then you access them, MyVar.x, MyVar.y, etc. – WakeskaterX Commented Apr 14, 2015 at 20:24
- Along with the namespace approach (elegantcode./2011/01/26/basic-javascript-part-8-namespaces), you could just simply using a self invoking anonymous function which would encapsulate any variables defined in it to that scope, instead of global. However, there might be a better approach someone could provide, depending on your use case. Have an example of what you mean by "toggle various properties" ? – Daved Commented Apr 14, 2015 at 20:29
- Use jQuery.data() - api.jquery./data instead of globals – Igor Commented Apr 14, 2015 at 20:30
- @Daved: What I meant by various properties is 1 global variable to toggle font-size property, 2nd global variable to toggle width maybe, etc. – user4774980 Commented Apr 14, 2015 at 20:37
- @NomNom99 When you toggle, for any of them, are the styles set enough that you could leverage a CSS class instead of styles on the element? Since you're using jQuery, you could really simplify things if this is the case. – Daved Commented Apr 14, 2015 at 20:54
5 Answers
Reset to default 3You can do this by using addEventListener to bind to the click event in bination 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>
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'
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...
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/sbznrhgy/1/
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./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./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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Click me three times</button>