最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Appropriate way to toggle in JavascriptjQuery without using global variables? - Stack Overflow

programmeradmin0浏览0评论

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?

Share Improve this question asked Apr 14, 2015 at 20:23 user4774980user4774980 5
  • 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
Add a ment  | 

5 Answers 5

Reset to default 3

You 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>

发布评论

评论列表(0)

  1. 暂无评论