Skip to main content
added 2711 characters in body
Source Link
phyrfox
  • 1
  • 4
  • 9

This final version, http://jsfiddle.net/dx9omcwd/11/, works the same as the original code, using just 35 lines of code. Included here is the JS code.

var info = {};
var div = [ac, al, am, ap, ba, ce, dsf, es, go, ma, mg, ms, mt, pa, pb, pe, pi, pr, rj, rn, ro, rr, rs, sc, se, sp, to];
var div1 = [ac1, al1, am1, ap1, ba1, ce1, dsf1, es1, go1, ma1, mg1, ms1, mt1, pa1, pb1, pe1, pi1, pr1, rj1, rn1, ro1, rr1, rs1, sc1, se1, sp1, to1];
function esconder() {
    $(div).slideUp("slow");
    $(div1).hide();
}

$(function () {
    var botao = ['aclegenda', 'allegenda', 'amlegenda', 'aplegenda', 'balegenda', 'celegenda', 'dflegenda', 'eslegenda', 'golegenda', 'malegenda', 'mglegenda', 'mslegenda', 'mtlegenda', 'palegenda', 'pblegenda', 'pelegenda', 'pilegenda', 'prlegenda', 'rjlegenda', 'rnlegenda', 'rolegenda', 'rrlegenda', 'rslegenda', 'sclegenda', 'selegenda', 'splegenda', 'tolegenda'];
    var botao1 = ['acre', 'alagoas', 'amazonas', 'amapa', 'bahia', 'ceara', 'df', 'espiritosanto', 'goias', 'maranhao', 'minasgerais', 'matogrossosul', 'matogrosso', 'para', 'paraiba', 'pernambuco', 'piaui', 'parana', 'riodejaneiro', 'riograndenorte', 'rondonia', 'roraima', 'riograndesul', 'santacatarina', 'sergipe', 'saopaulo', 'tocantins'];
    
    function prepare() {
        var index = 0;
        while (index < botao.length) {
            info[botao[index]] = info[botao1[index]] = [div[index], div1[index]];
            index = index + 1;
        }
    }
    prepare();
    esconder();
    $('.container').on('click', '.legendalinks.jsvoidcursor, .linksestados1',
                       function () {
                           var id = $(this).attr('id'),
                               curr = info[id];
                           if ($(curr[0], curr[1]).is(':visible')) {
                               $(curr[0]).slideUp('slow');
                               $(curr[1]).hide();
                           } else {
                               esconder();
                               $(curr[0]).slideDown('slow');
                               $(curr[1]).show();
                           }
                       });
});

I'm sure this could be optimized even more, but this answer was meant only to illustrate the use of on to minimize the amount of code that has to be written. In this case, using just one single function with some prepared data greatly reduces the amount of data that's necessary.

Further optimizations would be to use objects instead of just plain arrays to associate the data.


This final version, http://jsfiddle.net/dx9omcwd/11/, works the same as the original code, using just 35 lines of code. Included here is the JS code.

var info = {};
var div = [ac, al, am, ap, ba, ce, dsf, es, go, ma, mg, ms, mt, pa, pb, pe, pi, pr, rj, rn, ro, rr, rs, sc, se, sp, to];
var div1 = [ac1, al1, am1, ap1, ba1, ce1, dsf1, es1, go1, ma1, mg1, ms1, mt1, pa1, pb1, pe1, pi1, pr1, rj1, rn1, ro1, rr1, rs1, sc1, se1, sp1, to1];
function esconder() {
    $(div).slideUp("slow");
    $(div1).hide();
}

$(function () {
    var botao = ['aclegenda', 'allegenda', 'amlegenda', 'aplegenda', 'balegenda', 'celegenda', 'dflegenda', 'eslegenda', 'golegenda', 'malegenda', 'mglegenda', 'mslegenda', 'mtlegenda', 'palegenda', 'pblegenda', 'pelegenda', 'pilegenda', 'prlegenda', 'rjlegenda', 'rnlegenda', 'rolegenda', 'rrlegenda', 'rslegenda', 'sclegenda', 'selegenda', 'splegenda', 'tolegenda'];
    var botao1 = ['acre', 'alagoas', 'amazonas', 'amapa', 'bahia', 'ceara', 'df', 'espiritosanto', 'goias', 'maranhao', 'minasgerais', 'matogrossosul', 'matogrosso', 'para', 'paraiba', 'pernambuco', 'piaui', 'parana', 'riodejaneiro', 'riograndenorte', 'rondonia', 'roraima', 'riograndesul', 'santacatarina', 'sergipe', 'saopaulo', 'tocantins'];
    
    function prepare() {
        var index = 0;
        while (index < botao.length) {
            info[botao[index]] = info[botao1[index]] = [div[index], div1[index]];
            index = index + 1;
        }
    }
    prepare();
    esconder();
    $('.container').on('click', '.legendalinks.jsvoidcursor, .linksestados1',
                       function () {
                           var id = $(this).attr('id'),
                               curr = info[id];
                           if ($(curr[0], curr[1]).is(':visible')) {
                               $(curr[0]).slideUp('slow');
                               $(curr[1]).hide();
                           } else {
                               esconder();
                               $(curr[0]).slideDown('slow');
                               $(curr[1]).show();
                           }
                       });
});

I'm sure this could be optimized even more, but this answer was meant only to illustrate the use of on to minimize the amount of code that has to be written. In this case, using just one single function with some prepared data greatly reduces the amount of data that's necessary.

Further optimizations would be to use objects instead of just plain arrays to associate the data.

Source Link
phyrfox
  • 1
  • 4
  • 9

You can bind a single click to many elements using a class selector, etc. this refers to the element that ended up being the target/srcElement for the event.

$('.toggleable').click(function() {
   if($(this).is(':visible')) {
       $(this).slideUp('slow');
       $(this).find('.innerDiv').hide();
   } else {
       $(this).slideDown('slow');
       $(this).find('.innerDiv').show();
   }
});

Under the covers, each matching element will get its own closure, and therefore operate correctly. I'm assuming in this code that one div is contained within the other (there's no HTML here). It's pretty trivial to use other methods, such as finding siblings, etc.

In an absolutely worst-case scenario, you can use data attributes on the clickable element to target other named elements, or you could make a named map:

var assoc = {
    ac: ac1, al: al1, /* and so on */ };
$('#ac, #al').click(function() {
   if($(this).is(':visible')) {
       $(this).slideUp('slow');
       $(assoc[this.id]).hide();
   } else {
       $(this).slideDown('slow');
       $(assoc[this.id]).show();
   }
});

I'd rather prefer the first method, as you can then add/remove elements in your HTML without having to refactor code.

There's plenty of other ways you could do this dynamically, including using $.on to bind to a parent element and then determine which element was clicked.

// uses assoc from prior example
$('#parent').on('click','.toggleable', function() {
    var id = $(this).attr('id'), v1 = $(this), v2 = assoc[id];
    if(v1.is(':visible')) {
        v1.slideUp('slow');
        v2.hide();
    } else {
        v1.slideDown('slow');
        v2.show();
    }
});

This final version allows new .toggleable elements to be added to #parent on the fly, and they will also react correctly (assuming they are styled, loaded into assoc, etc).