申请 D.R.Y 时遇到问题。我的 jQuery

Having trouble applying D.R.Y. to my jQuery

我需要帮助来简化我的代码。我正在尝试应用 D.R.Y。尽我所能,我遇到了麻烦。任何帮助将不胜感激。

$('document').ready(function(){
    'use strict';

    var body = $('body');

    body.find('#button1').click(function(){
         body.find('#item1').add('#item2').fadeOut();
         body.find('#item3').fadeIn();
         body.find('#button1').removeClass('btn-info').addClass('btn-default');
         body.find('#button2').removeClass('btn-default').addClass('btn-info');
    });

    body.find('#button2').click(function(){
        body.find('#item3').fadeOut();
        body.find('#item1').add('#item2').fadeIn();
        body.find('#button2').removeClass('btn-info').addClass('btn-default');
        body.find('#button1').removeClass('btn-default').addClass('btn-info');
    });
});

提前致谢!

似乎可以应用的一项 DRY 是针对 class 部分:

//add event bound to the click of a element with class btn-default
body.on('click', '.btn-default', function () {
    //remove btn-default from this class and add btn-info
    $(this).removeClass('btn-default').addClass('btn-info');
    //remove btn-info from this class and add btn-default
    $('.btn-info').removeClass('btn-info').addClass('btn-default');
});

制作整个代码:

$('document').ready(function(){
    'use strict';

    var body = $('body');

    //add event bound to the click of a element with class btn-default
    body.on('click', '.btn-default', function () {
        //remove btn-default from this class and add btn-info
        $(this).removeClass('btn-default').addClass('btn-info');
        //remove btn-info from this class and add btn-default
        $('.btn-info').removeClass('btn-info').addClass('btn-default');
    });

    body.find('#button1').click(function(){
         body.find('#item1').add('#item2').fadeOut();
         body.find('#item3').fadeIn();
    });

    body.find('#button2').click(function(){
        body.find('#item3').fadeOut();
        body.find('#item1').add('#item2').fadeIn();
    });
});

没有不必要的重复,但是有多余的代码。例如,不需要从 $('body').find() 下一个标签开始。

相反,请遵循以下模式:

(1) 删除 var body = $('body'); -- 不需要

(2) 进行以下更改:

body.find('#button1').click( -- can be -- $('#button1').click(

body.find('#item1').add('#item2').fadeOut(); == $('#item1').add('#item2').fadeOut();

body.find('#item3').fadeIn();  ==  $('#item3').fadeIn();

等等


更新:为了减少 DOM 搜索,缓存整个选择器:

$('document').ready(function(){
    'use strict';
    var $i1 = $('#item1');
    var $i3 = $('#item3')
    var $b1 = $('#button1');
    var $b2 = $('#button2');

    $b1.click(function(){
         $i1.add('#item2').fadeOut();
         $i3.fadeIn();
         $b1.removeClass('btn-info').addClass('btn-default');
         $b2.removeClass('btn-default').addClass('btn-info');
    });

    $b2.click(function(){
        $i3.fadeOut();
        $i1.add('#item2').fadeIn();
        $b2.removeClass('btn-info').addClass('btn-default');
        $b1.removeClass('btn-default').addClass('btn-info');
    });
});

您可以创建一个函数(比如 'toggleElements'),它接受一个标志并根据标志的值执行所有需要的操作,然后执行此操作:

body.find('#button1').click(function() {
    toggleElements(true);
});

我看不出您的代码有任何问题,任何更改都不会提高可读性。它并不总是 "do whatever you can, but do not repeat a single line of code" - 你需要找到最佳的,你的外表真的很好。

但是,有一些可能的改进:

  1. 如果您的元素 ID 是唯一的,为什么还要使用 body?您可以简单地使用选择器。

  2. 您可以组合选择器而不是使用 .add

类似于:

$('document').ready(function(){
    'use strict';

    $('#button1').click(function(){
         $('#item1, #item2').fadeOut();
         $('#item3').fadeIn();
         $('#button1').removeClass('btn-info').addClass('btn-default');
         $('#button2').removeClass('btn-default').addClass('btn-info');
    });

    $('#button2').click(function(){
        $('#item3').fadeOut();
        $('#item1,#item2').fadeIn();
        $('#button2').removeClass('btn-info').addClass('btn-default');
        $('#button1').removeClass('btn-default').addClass('btn-info');
    });
});

另一种选择是将此功能组合到一个带有布尔参数的函数中,或者使用 CSS 类 和转换。正如我所说,在我看来,4行代码不是"optimized"就可以了。如果你的函数长大了 - 优化它。

除了仅使用 $ 来访问唯一的元素之外,您可能还喜欢它作为对重用性和可读性的改进,

function makeInfo(id) {
  $(id).removeClass('btn-default').addClass('btn-info');
}
function makeDefault(id) {
  $(id).removeClass('btn-info').addClass('btn-default');
}

$('document').ready(function(){
    'use strict';

    $('#button1').click(function(){
         $('#item1').add('#item2').fadeOut();
         $('#item3').fadeIn();
         makeInfo('#button2');
         makeDefault(this);             
    });

    $('#button2').click(function(){
        $('#item3').fadeOut();
        $('#item1').add('#item2').fadeIn();
        makeInfo('#button1');
        makeDefault(this);             
    });
});

您可以尝试这样的操作,您可以在每个按钮上使用 data 属性来定义要显示的项目。这样做的好处是,当您需要添加更多按钮或项目时需要更少的工作,并且适用于任何 buttons/items 组合。

jsFiddle

HTML:

<input type="button" id="button1" class="btn-info" value="Button 1" data-show="#item1" />
<input type="button" id="button2" class="btn-default" value="Button 2" data-show="#item2" />
<input type="button" id="button3" class="btn-default" value="Button 3" data-show="#item2, #item3" />

<div id="item1" class="itemClass">Item 1</div>
<div id="item2" class="itemClass">Item 2</div>
<div id="item3" class="itemClass">Item 3</div>

JS:

$('body').on('click', '.btn-default', function() {
  var show = $(this).data('show');
  $('.itemClass').not(show).fadeOut();
  $(show).fadeIn();

  $('.btn-info').addClass('btn-default').removeClass('btn-info');
  $(this).addClass('btn-info').removeClass('btn-default');
});