重构/优化一大块jQuery代码的技巧

时间:2011-11-18 15:55:27

标签: jquery optimization refactoring

我正在使用工具提示使用jquery构建一个小“漫游”类型指南。

当页面加载时,页面的一部分将有一个工具提示,旁边显示“步骤1”,当他们点击所需区域时,该消失,“步骤2”将显示在页面的下方。

我的代码有效,但我只是在寻找有关如何改进和优化我所写内容的建议,或者是一种简化整个过程的方法。我已经尝试过在$('。helpTip')选择器等地方使用变量,但我相信我必须在每个点击功能中定义那个有点无意义的变量吗?

无论如何,代码:

$('.box1').append('<div class="helpTip">Step 1. <span>text</span></div>');

$('.box1 li').click(function() {
    $('.helpTip').fadeOut().remove();
    $('.box2').append('<div class="helpTip">Step 2. <span>text</span></div>');
});

$('.box2 p').click(function() {
    $('.helpTip').fadeOut().remove();
    $('.box3').append('<div class="helpTip">Step 3. <span>text</span></div>');
});

$('.box3 div').click(function() {
    $('.helpTip').fadeOut().remove();
    $('.box4').append('<div class="helpTip">Step 4. <span>text</span></div>');
});

$('.box4 div').click(function() {
    $('.helpTip').fadeOut().remove();
    $('.box5').append('<div class="helpTip">Step 5. <span>text</span></div>');
});

$('.box5').click(function() {
    $('.helpTip').fadeOut().remove();
    // Do something to the submit button?
});

HTML如果有帮助:

<!-- Step 1 -->
<div class="formWrap">  
    <div class="formInner">
        <div class="formHeader">
            <h3>1. </h3>
        </div>
        <div class="box1">

        </div>
    </div>                      
</div>

<!-- Step 2 -->
<div class="formWrap">
    <div class="formInner">
        <div class="box2">

        </div>
    </div>
</div>                  

<!-- Step 3 -->
<div class="formWrap">
    <div class="formInner">
        <h3 class="formHeader">3. </h3>
        <div class="box3">

        </div>
    </div>
</div>  

<!-- Step 4 -->
<div class="formWrap">
    <div class="formInner">
        <h3 class="formHeader">4. </h3>
        <div class="box4">


        </div>
    </div>
</div>

<!-- Step 5 -->
<div class="formWrap">
    <div class="formInner">
        <h3 class="formHeader">5. </h3>
        <div class="box5">

        </div>
    </div>
</div>  

3 个答案:

答案 0 :(得分:2)

以下是我的建议,FWIW:

  • 如果没有其他类别为“box1”的元素,我会改变 那是一个ID。然后你可以使用just来定位元素 $('#box1')而且会快得多。
  • 您可以使用delegate()方法定位“box”元素下的元素。这是
    通常更有效率。所以你最终会得到$('#box1').delegate('li', 'click', function () {});
  • 使用上下文可以提高查询效率。例如,$('.helpTip')将搜索整个DOM,查找具有“helpTip”类的任何元素。看起来你要做的只是在当前框内只定位“helpTip”。
  • 尽可能多地缓存查询。

基本上代码更像是:

var $box1 = $('#box1'),
    $box2 = $('#box2'),
    $box3 = $('#box3'),
    $box4 = $('#box4'),
    $box5 = $('#box5');
$box1.delegate('li', 'click', function () {
    var $this  = $(this);
    $('.helpTip', $this).fadeOut().remove();
    $box2.append('<div class="helpTip">Step 2. <span>text</span></div>');
});

等等......

答案 1 :(得分:1)

对于初学者,将jQuery上下文存储在变量中,第二次使用委托,live或new on来附加事件。

e.g。

    var box1 = $('.box1');
    var box2 = $('.box2');

    box1.append('<div class="helpTip">Step 1. <span>text</span></div>');

    $('li', box1).on("click", function() {
        $('.helpTip').fadeOut().remove();
        box2.append('<div class="helpTip">Step 2. <span>text</span></div>');
    });
...

你也可以这样做:

var box1 = $('.box1');
var box2 = $('.box2');
var box3 = $('.box3');
var box4 = $('.box4');
var box5 = $('.box5');

$('.box1 li, .box2 p, .box3 div, .box4 div, .box5').on("click", function() {
    var currentContext = $(this);   
        $('.helpTip', currentContext).fadeOut().remove();

    if (currentContext.hasClass(".box5")) {
        // Do something to the submit button        
    }
    else {
        // write some method to figure out which box to append help to.
    }
});

答案 2 :(得分:1)

你不能循环包含元素的数组吗?类似的东西:

var appended = ['Step 1. <span>text</span>',
            'Step 2. <span>text</span>',
            'Step 3. <span>text</span>',
            'Step 4. <span>text</span>',
            'Step 5. <span>text</span>'
            ];
var selector = ['.box1 li','.box2 div','.box3 div','.box4 div','.box5']
var help = $('.helpTip');
function fader(){
    help.fadeOut().remove();
}
$('.box1').append('<div class="helpTip">'+appended[0]+'</div>');
var i = 0;
var box = '.box';
$(selector[i]).live('click',function(){ //if the elements already exist you should use .click or bind('click')wasn't sure if this was the situation

    app = box+(i+2);
    if (app === '.box5'){
        fader();   
    } else {
        fader();
        $(app).append('<div class="helpTip">'+appended[i+1]+'</div>')
        i++;    
    }


})

对不起,我可以测试一下(我身边没有时间,而且你身边缺乏html ..更好地为这样的问题附上一个jsfiddle)所以基本上这是伪代码。不确定这会优化速度(这已经很好地涵盖了@ Mike-McCaughan的回答)但如果这个列表更长,它会更好地扩展,也会保持干燥。

如果您按照@ Mike-McCaughan的建议,那么可以删除'selector'数组,并根据需要更改函数的开头