简体   繁体   中英

Refactoring Code

Let's say I have the following code:

    $(function () {
    $(".buy-it-now.ribbon").click(function () {
        $(".bid-to-beat.ribbon.active").removeClass("active");
        $(".bid-to-beat.ribbon").addClass("inactive");
        $(".buy-it-now.ribbon.inactive").removeClass("inactive");
        $(".buy-it-now.ribbon").addClass("active");
        $(".bid-now").hide();
        $(".buy-now").show();
        $(".add-to-cart").hide();
    })
    $(".bid-to-beat.ribbon").click(function () {
        $(".buy-it-now.ribbon.active").removeClass("active");
        $(".buy-it-now.ribbon").addClass("inactive");
        $(".bid-to-beat.ribbon").removeClass("inactive");
        $(".bid-to-beat.ribbon").addClass("active");
        $(".buy-now").hide();
        $(".bid-now").show();
        $(".add-to-cart").show();
    });
});

It is a simple function that allows for multiple UI related things to happen on the front-end of a site I am working on. I am fairly (very) new to jQuery and JavaScript in general and am learning about refactoring and making my code more condensed now. The way I currently write code is sort of line per thought I have. So my question is how would an experienced developer write this same code? Or rather, how could I refactor this code?

Try the following:

$(function () {
    var $handlers = $('.buy-it-now.ribbon, .bid-to-beat.ribbon');

    $handlers.click(function() {
        $handlers.toggleClass("active inactive");

        var $elements = $(".bid-now, .add-to-cart"),
            $buyElement = $(".buy-now");

        if($(this).is('.buy-it-now.ribbon')) {
            $elements.hide();
            $buyElement.show();
        } else {
            $elements.show();
            $buyElement.hide();
        }
    });
});

This question would be better suited for codereview, but yes it can be condensed a little using method chaining.

$(function () {
    $(".buy-it-now.ribbon").click(function () {
        $(".bid-to-beat.ribbon").removeClass("active").addClass("inactive");
        $(".buy-it-now.ribbon").removeClass("inactive").addClass("active");
        $(".bid-now").hide();
        $(".buy-now").show();
        $(".add-to-cart").hide();
    })
    $(".bid-to-beat.ribbon").click(function () {
        $(".buy-it-now.ribbon").removeClass("active").addClass("inactive");
        $(".bid-to-beat.ribbon").removeClass("inactive").addClass("active");
        $(".buy-now").hide();
        $(".bid-now").show();
        $(".add-to-cart").show();
    });
});

You could condense it further by pre selecting the elements and caching them in variables before the click events as long as no elements are added or removed during the life of the page.

As your code it is you can combine some of the selectors into a single line. And also because your elements looks to be static you can cache them into a variable and use them later as it reduces the number of times a element is looked up in the DOM reducing the accessing time..

Also you can limit the scope of these variables or selectors by encasing them in an object or a closure..

Maybe something in these lines..

       $(function () {
   cart.init();
});

var cart = {
    elems : {
        $buyRibbon : null,
        $bidRibbon : null,
        $bidNow: null,
        $buyNow: null,
        $addToCart: null
    },
    events : {
    },
    init : function() {
        this.elems.$buyRibbon = $(".buy-it-now.ribbon");
        this.elems.$bidRibbon = $(".bid-to-beat.ribbon");
        this.elems.$bidNow = $(".bid-now") ;
        this.elems.$buyNow = $(".buy-now") ;
        this.elems.$addToCart = $(".add-to-cart") ;
        this.events.buyClick();
        this.events.bidClick();
    }
};

cart.events.buyClick = function() {
    cart.elems.$buyRibbon.on('click', function(){
        cart.elems.$bidRibbon.removeClass('active').addClass('inactive');
        cart.elems.$buyRibbon.removeClass('inactive').addClass('active');
        cart.elems.$bidNow.hide();
        cart.elems.$buyNow.show();
        cart.elems.$addToCart.hide();
    });
} 

cart.events.bidClick = function() {
    cart.elems.$bidRibbon.on('click', function(){
        cart.elems.$buyRibbon.removeClass('active').addClass('inactive');
        cart.elems.$bidRibbon.removeClass('inactive').addClass('active');
        cart.elems.$bidNow.show();
        cart.elems.$buyNow.hide();
        cart.elems.$addToCart.show();
    });
} 

So basically in here your whole cart is a object ..And the cart has different properties which are related to this.. You follow the principles of object oriented programming here.. Using closures I heard gives you better design limiting the scope of your code..

Might I suggest something like this:

$(function () {
    var buyNowButton = $('buy-it-now.ribbon'),
        bidToBeatButton = $('.bid-to-beat.ribbon'),
        buyNowEls = $('.buy-now'),
        bidToBeatEls = $('.bid-now,.add-to-cart');

    var toggleButtons = function(showBuyNow){
        buyNowButton.toggleClass('active', showBuyNow);
        bidToBeatButton.toggleClass('active', !showBuyNow);
        buyNowEls.toggle(showBuyNow);
        bidToBeatEls.toggle(!showBuyNow);
    }

    buyNowButton.click(function(){ toggleButtons(true) });
    bidToBeatButton.click(function(){ toggleButtons(false) });
});

You could save a some lines by removing the selectors at the start and just do the selection in place, if the saved space would be more important than the minor performance hit. Then it would look like this:

$(function () {
    var toggleButtons = function(showBuyNow){
        $('buy-it-now.ribbon').toggleClass('active', showBuyNow);
        $('.bid-to-beat.ribbon').toggleClass('active', !showBuyNow);
        $('.buy-now').toggle(showBuyNow);
        $('.bid-now,.add-to-cart').toggle(!showBuyNow);
    }

    $('buy-it-now.ribbon').click(function(){ toggleButtons(true) });
    $('.bid-to-beat.ribbon').click(function(){ toggleButtons(false) });
});

The first version selects the elements once and holds them in memory; the second selects them each time the button is clicked. Both solve the problem I believe would occur with the selected answer where clicking the same button twice would cause the .active and .inactive classes to get out of sync with the shown/hidden elements.

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