简体   繁体   English

重构代码

[英]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. 这是一个简单的功能,它允许在我正在处理的网站的前端发生与UI相关的多种事情。 I am fairly (very) new to jQuery and JavaScript in general and am learning about refactoring and making my code more condensed now. 我对jQuery和JavaScript相当(非常)陌生,现在正在学习有关重构和使我的代码更简洁的知识。 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. 只要在页面有效期内不添加或删除任何元素,就可以通过预选择元素并将它们缓存在click事件之前的变量中来进一步精简它。

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.. 另外,由于您的元素看起来是静态的,因此您可以将它们缓存到变量中,并稍后使用它们,因为它减少了在DOM中查找元素的次数,从而减少了访问时间。

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. 两者都解决了我认为会与所选答案有关的问题,其中单击同一按钮两次将导致.active和.inactive类与显示/隐藏的元素不同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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