简体   繁体   中英

How can I reuse a variable in a different scope?

I am trying to figure out how I can reuse a variable within a function, right now I have to put it in each scope for it to work.

Say I have an jQuery Event handler:

$('.button').on('click', function() {
    var btn = $(this).data('button');
    $(this).addClass(btn+'-activate');
}).on('mouseup', function() {
     var btn = $(this).data('button');
     $(this).removeClass( btn+'-activate');
}).on('mouseleave', function() {
     var btn = $(this).data('button');
     $(this).removeClass( btn+'-activate');
}

How can I reuse the variable 'btn'? When I put it in the parent scope, it doesn't recognize $(this) anymore

The other answers have a bit of redundancy in them. Here is how I usually handle events that are related and have common variables:

$('.button').on('click mouseup mouseleave', function(event) {
    var btn = $(this).data('button');

    switch(event.type) {
        case 'click': {
            $(this).addClass(btn+'-activate');
            break;
        }

        case 'mouseup':
        case 'mouseout':
        case 'mouseleave': {
            $(this).removeClass(btn+'-activate');
            break;
        }
    }
});

Listen to multiple events and use a switch statement to determine which event was called.

You can just iterate over the buttons, set the variable for each one and then use the variable inside the event handlers.

$('.button').each(function() {
    var btn = $(this).data('button');
    $(this).on('click', function() {
        $(this).addClass(btn+'-activate');
    }).on('mouseup mouseleave', function() {
        $(this).removeClass( btn+'-activate');
    });
});

But of course this is not exactly the same as your code. Here we are setting the value of btn at the time the handlers are attached while, in the code of the question, btn is set at the time the handlers are called. Therefore this is only a valid alternative if the value of .data('button') is not meant to change.

There's no special advantage to using a variable. You can pass a function to .removeClass() and .addClass() thereby removing the need to use a variable:

$(function() {
    $('.button').on('click', function() {
        $(this).addClass( function() {
            return $(this).data('button') + '-activate';
        });
    }).on('mouseup mouseleave', function() {
         $(this).removeClass( function() {
             return $(this).data('button') + '-activate';
         });
    });
});

  $(function() { $('.button').on('click', function() { $(this).addClass( function() { return $(this).data('button') + '-activate'; }); }).on('mouseup mouseleave', function() { $(this).removeClass( function() { return $(this).data('button') + '-activate'; }); }); }); 
 .one-activate { background-color:black; color:white; } .two-activate { background-color:black; color:yellow; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <button class="button" data-button="one">Man</button><br/> <button class="button" data-button="two">Woman</button><br/> 

BONUS :

As you can see the functions passed to .removeClass() and .addClass() are exactly identical. We could write a jQuery custom method and use it in place of the functions as follows:

$(function() {
    $('.button').on('click', function() {
        $(this).addClass( $(this).btnActivate() );
    })
    .on('mouseup mouseleave', function() {
         $(this).removeClass( $(this).btnActivate() );
    });
});

$.fn.btnActivate = function() {
    return this.data('button') + '-activate';
};

  $(function() { $('.button').on('click', function() { $(this).addClass( $(this).btnActivate() ); }) .on('mouseup mouseleave', function() { $(this).removeClass( $(this).btnActivate() ); }); }); $.fn.btnActivate = function() { return this.data('button') + '-activate'; }; 
 .one-activate { background-color:black; color:white; } .two-activate { background-color:black; color:yellow; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <button class="button" data-button="one">Man</button><br/><br/> <button class="button" data-button="two">Woman</button><br/> 

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