简体   繁体   中英

How can I simplify these multiple/similar click events in jQuery/Javascript?

I have several buttons on my page for which I'm assigning similar click events. The code below works fine, but is there a way I can loop/simplify the repetitive blocks below? I tried a for loop but it didn't work.

var functionName = "step";

$("#stepbox1").click(function(){
$("#step1").show();                    
$("#stepswrapper section").not("#step1").hide();
$("#stepbox1").addClass("stepboxactive");
$("#stepboxmain div").not("#stepbox1").removeClass("stepboxactive");
myFunctions[functionName + 1]();
});

$("#stepbox2").click(function(){
$("#step2").show();                    
$("#stepswrapper section").not("#step2").hide();
$("#stepbox2").addClass("stepboxactive");
$("#stepboxmain div").not("#stepbox2").removeClass("stepboxactive");
myFunctions[functionName + 2]();
});

$("#stepbox3").click(function(){
$("#step3").show();                    
$("#stepswrapper section").not("#step3").hide();
$("#stepbox3").addClass("stepboxactive");
$("#stepboxmain div").not("#stepbox3").removeClass("stepboxactive");
myFunctions[functionName + 3]();
});

// And another three of those…

This loop will NOT work:

for (i = 1; i < 7; i++) {
$("#stepbox" + i).click(function(){
$("#step" + i).show();                     
$("#stepswrapper section").not("#step" + i).hide();
$("#stepbox" + i).addClass("stepboxactive");
$("#stepboxmain div").not("#stepbox" + i).removeClass("stepboxactive");
myFunctions[functionName + i]();
});
}

You can use div[id*=stepbox] to retrieve the array of divx since they all have stepbox common in their IDs. Then you can get the index of the each element and use it in the rest of the code. (It is a 0-based array that is why I added +1 at the beginning).

 $("div[id*=stepbox]").click(function(){
    int myIndex = $(this).index() + 1;
    $("#step" + myIndex).show();                    
    $("#stepswrapper section").not("#step" + myIndex).hide();
    $("#stepbox" + myIndex).addClass("stepboxactive");
    $("#stepboxmain div").not("#stepbox" + myIndex).removeClass("stepboxactive");
    myFunctions[functionName + myIndex]();
 });

If you can update your HTML then here is a cleaner approach:

<div id="stepbox1" class="stepboxactive stepbox" data-box-id="1">
  <strong>Step 1</strong><br />
  Your name
</div>
<div id="stepbox2" class="stepbox" data-box-id="2">
  <strong>Step 2</strong><br />
  Divider
</div>
<div id="stepbox3" class="stepbox" data-box-id="3">
  <strong>Step 3</strong><br />
  Font
</div>
<div id="stepbox4" class="stepbox" data-box-id="4">
  <strong>Step 4</strong><br />
  Shapes
</div>
<div id="stepbox5" class="stepbox" data-box-id="5">
  <strong>Step 5</strong><br />
  Color
</div>
<div id="stepbox6" class="stepbox" data-box-id="6">
  <strong>Step 6</strong><br />
  Export it
</div>

Then your code can attach to any div with the class stepbox and it can get it's ID from a data attribute (you can see how you can extend this system to non-sequential IDs or even alphanumeric IDs. Your code might look something like this:

$(".stepbox").click(function() {
  var id = $(this).data('box-id');

  $("#step"+id).show();                    
  $("#stepswrapper section").not("#step"+id).hide();
  $("#stepbox"+id).addClass("stepboxactive");
  $("#stepboxmain div").not("#stepbox"+id).removeClass("stepboxactive");
  myFunctions[functionName + id]();
});

You should keep the access to i variable with closures:

for (i = 1; i < 7; i++) {
    $("#stepbox" + i).click((function (j) { // create the closure here
        return function () {
            // now work with `j` instead of `i`
            $("#step" + j).show();
            $("#stepswrapper section").not("#step" + j).hide();
            $("#stepbox" + j).addClass("stepboxactive");
            $("#stepboxmain div").not("#stepbox" + j).removeClass("stepboxactive");
            myFunctions[functionName + j]();
        };
    }(i))); // pass the `i` variable to closure
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM