jQuery干涸功能

时间:2012-11-21 14:39:13

标签: javascript jquery if-statement refactoring dry

正如您在下面所见,我明确地重复了一遍。我知道这是不好的做法。

那么,如何将if和else语句中的4个重复代码行重构为一个?

非常感谢对更好实践的一些指导。此外,您发现有助于学习此技术的任何DRY参考/教程。

$('.inner_wrap .details').click(function() {
    var index = $('.inner_wrap .details').index(this);

    $('.details').removeClass('here');
    $(this).addClass('here');
    $('.view').removeClass('active');
    $(this).find('.view').addClass('active');
    console.log(index);
    if(index > 2){
        index -= 3;
        **// This and its corresponding else statement is the topic of the question**
        $(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow');
        $(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide:eq(' + index + ')').addClass('tabShow');
    } else {
        $(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow');
        $(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide:eq(' + index + ')').addClass('tabShow');
    }

    return false;
});

5 个答案:

答案 0 :(得分:4)

请注意,代码在ifelse中都会重复,这意味着它始终会执行。把它从陈述中删除:

if (index > 2) {
    index -= 3;
}
var elt = $(this).closest('.outer_wrapper').prev('.outer_wrapper');
elt.find('.tabSlide').removeClass('tabShow');
elt.find('.tabSlide:eq(' + index + ')').addClass('tabShow');

接下来,请注意jQuery对象只是一个数组。因此,您可以简化代码:

if (index > 2) {
    index -= 3;
}
var elt = $(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide');
$(elt.removeClass('tabShow')[index]).addClass('tabShow');

最后,我们可以消除aux变量,仅用于演示如何调用同一个对象:

if (index > 2) {
    index -= 3;
}
$($(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow')[index]).addClass('tabShow');

请将其分解为多行代码:D

[编辑]

好的,只是为了好玩,这里是一个更加极端的宇航员类型的代码,摆脱剩余的if

$($(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow')[(index <= 2 ? index : index - 3)]).addClass('tabShow');

BUT!它非常难以理解和IMO,你应该坚持第一步。在它成为性能问题之前,不要过度使用它。以可读性/可维护性为代价应用DRY规则或者只是将所有内容都放在一行代码中就像阅读和阅读一样有意义。编写缩小代码。即,不要这样做:)。

[编辑2]

@StuartNelson提醒我$.eq()函数的存在,它会将最终代码带到此(分为几行):

$(this).closest('.outer_wrapper')
    .prev('.outer_wrapper')
    .find('.tabSlide')
    .removeClass('tabShow')
    .eq(index <= 2 ? index : index - 3)
    .addClass('tabShow');

答案 1 :(得分:2)

您只能使用index语句修改if,并且可以为所使用的jQuery元素保留一个变量:

$('.inner_wrap .details').click(function() {
    var index = $('.inner_wrap .details').index(this);

    $('.details').removeClass('here');
    $(this).addClass('here');
    $('.view').removeClass('active');
    $(this).find('.view').addClass('active');
    console.log(index);
    if(index > 2){
       index -= 3;
    }
    var element = $(this).closest('.outer_wrapper').prev('.outer_wrapper');
    element.find('.tabSlide').removeClass('tabShow');
    element.find('.tabSlide:eq(' + index + ')').addClass('tabShow');   
    return false;
});

答案 2 :(得分:1)

这两行在if和else子句中都是最后执行的,因此可以将它们从两者中拉出并放在整个if / else语句之后:

if(index > 2){
    index -= 3;
}

$(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow');
$(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide:eq(' + index + ')').addClass('tabShow');

这条规则总是如此。如果它们是if和else子句中的前两行,则将它们拉出来并将它们放在if语句之前。

答案 3 :(得分:1)

因为您真正关心的是设置索引,这是您在if staement中唯一需要的东西,其余的可以出去:

if(index > 2){
    index -= 3;
}

$(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide').removeClass('tabShow');
$(this).closest('.outer_wrapper').prev('.outer_wrapper').find('.tabSlide:eq(' + index + ')').addClass('tabShow');

答案 4 :(得分:1)

if(index > 2){ index -= 3; }
**// This and its corresponding else statement is the topic of the question**
$(this).closest('.outer_wrapper').prev('.outer_wrapper')
       .find('.tabSlide').removeClass('tabShow')
       .eq(index).addClass('tabShow')

抛弃其他人,因为无论您是否需要将其包含在声明中,您都要执行该代码。您也可以继续处理链,因为您首先使用类tabSlide定位所有元素,然后根据其索引仅定位该类的特定实例。