4

正如你在下面看到的,我清楚地重复了一遍。我知道这是不好的做法。

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

一些关于更好实践的指导将不胜感激。此外,您发现有助于学习此技术的任何 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;
});
4

5 回答 5

4

请注意,代码在if和中都重复,这else意味着它总是被执行。只需将其从声明中删除:

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');

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

[编辑 2]

@StuartNelson 让我想起了该$.eq()函数的存在,它会将最终代码带到这里(分成几行):

$(this).closest('.outer_wrapper')
    .prev('.outer_wrapper')
    .find('.tabSlide')
    .removeClass('tabShow')
    .eq(index <= 2 ? index : index - 3)
    .addClass('tabShow');
于 2012-11-21T15:01:53.133 回答
2

您可以修改indexonly usingif语句,并且可以为使用的 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;
});
于 2012-11-21T14:53:41.973 回答
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 语句之前。

于 2012-11-21T14:52:57.317 回答
1

由于您真正关心的是设置索引,这是您在 if 语句中唯一需要的,其余的可以出去:

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');
于 2012-11-21T14:55:07.120 回答
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')

放弃 else,因为您正在执行该代码,无论您不需要将其包含在语句中。您也可以继续在链上工作,因为您首先使用类定位所有元素,tabSlide然后根据其索引仅定位该类的特定实例。

于 2012-11-21T14:55:21.620 回答