【问题标题】:Best way to optimize and merge these Jquery functions优化和合并这些 Jquery 函数的最佳方法
【发布时间】:2016-04-24 15:20:13
【问题描述】:

我有 3 个函数都设置了点击事件,它们在各自的 div 中触发相同的函数。我想优化这一点,所以我不会一遍又一遍地重复自己。写这个的最好方法是什么?

//Progress Bar animation when tab clicked
$('#tab1').click(function () {
    $('#stack .progress div').each(function () {
        var display = $(this),
        currentValue = parseInt(display.text()),
        nextValue = $(this).attr('data-values'),
        diff = nextValue - currentValue,
        step = (0 < diff ? 1 : -1);
        if (nextValue == '0') {
            $(display).css('padding', '0');
        } else {
            $(display).css('color', '#fff').animate({
                'width': nextValue + '%'
            }, 'slow');
        }

        for (var i = 0; i < Math.abs(diff); ++i) {
            setTimeout(function () {
                currentValue += step
                display.html(currentValue + '%');
            }, 20 * i);
        }
    })
});
$('#tab2').click(function () {
    $('#design .progress div').each(function () {
        var display = $(this),
        currentValue = parseInt(display.text()),
        nextValue = $(this).attr('data-values'),
        diff = nextValue - currentValue,
        step = (0 < diff ? 1 : -1);
        if (nextValue == '0') {
            $(display).css('padding', '0');
        } else {
            $(display).css('color', '#fff').animate({
                'width': nextValue + '%'
            }, 'slow');
        }

        for (var i = 0; i < Math.abs(diff); ++i) {
            setTimeout(function () {
                currentValue += step
                display.html(currentValue + '%');
            }, 20 * i);
        }
    })
});
$('#tab3').click(function () {
    $('#other .progress div').each(function () {
        var display = $(this),
        currentValue = parseInt(display.text()),
        nextValue = $(this).attr('data-values'),
        diff = nextValue - currentValue,
        step = (0 < diff ? 1 : -1);
        if (nextValue == '0') {
            $(display).css('padding', '0');
        } else {
            $(display).css('color', '#fff').animate({
                'width': nextValue + '%'
            }, 'slow');
        }

        for (var i = 0; i < Math.abs(diff); ++i) {
            setTimeout(function () {
                currentValue += step
                display.html(currentValue + '%');
            }, 20 * i);
        }
    })
});

【问题讨论】:

    标签: jquery performance dry


    【解决方案1】:

    我更喜欢在一个烤箱里烧一件东西。如果你需要改变一件东西,你应该需要在一个地方改变它。

    function doAnimation() {
        var display = $(this),
        currentValue = parseInt(display.text()),
        nextValue = $(this).attr('data-values'),
        diff = nextValue - currentValue,
        step = (0 < diff ? 1 : -1);
        if (nextValue == '0') {
            $(display).css('padding', '0');
        } else {
            $(display).css('color', '#fff').animate({
                'width': nextValue + '%'
            }, 'slow');
        }
    
        for (var i = 0; i < Math.abs(diff); ++i) {
            setTimeout(function () {
                currentValue += step
                display.html(currentValue + '%');
            }, 20 * i);
        }
    }
    //Progress Bar animation when tab clicked
    $('#tab1').click(function () {
        $('#stack .progress div').each(doAnimation);
    });
    $('#tab2').click(function () {
        $('#design .progress div').each(doAnimation);
    });
    $('#tab3').click(function () {
        $('#other .progress div').each(doAnimation);
    });
    

    【讨论】:

    • 这会产生以下错误“Uncaught TypeError: Cannot read property 'call' of undefined”
    • 虽然我知道有多种方法可以做我想做的事,但这似乎使它变得非常简单和干燥,并且不需要在我的视图中添加任何额外的类型标签。谢谢!
    【解决方案2】:

    向代表选项卡的 HTML 标记添加数据属性。例如:

    data-progress="#stack"
    
    data-progress="#design"
    
    data-progress="#other"
    

    定义一个函数,像这样:

    function tabClicked() {
        $($(this).data("progress") + ' .progress div').each(function () {
            var display = $(this),
            currentValue = parseInt(display.text()),
            nextValue = $(this).attr('data-values'),
            diff = nextValue - currentValue,
            step = (0 < diff ? 1 : -1);
            if (nextValue == '0') {
                $(display).css('padding', '0');
            } else {
                $(display).css('color', '#fff').animate({
                    'width': nextValue + '%'
                }, 'slow');
            }
    
            for (var i = 0; i < Math.abs(diff); ++i) {
                setTimeout(function () {
                    currentValue += step
                    display.html(currentValue + '%');
                }, 20 * i);
            }
        });
    }
    

    并将其用作点击处理程序:

    $("#tab1, #tab2, #tab3").click(tabClicked);
    

    【讨论】:

    • 这很漂亮,请问您为什么要添加“数据进度”属性?如果标签已经有一个具有相同 id 引用的 href,它不会工作得很好吗?
    • @JuanPabloUgas,这是个好问题。添加了 data-progress 属性是因为三个单独的功能在函数开头和功能级别的 .each() 调用中使用了不同的选择器,我相信不知道选择器并使用 $(this) 会更优雅.data("progress") 代替。当且仅当我们定义数据属性时,.data() 调用才能工作。
    【解决方案3】:
    var progressTargets = {tab1 : "stack", tab2 : "design", tab3 : "other"};
    $('#tab1, #tab2, #tab3').click(function () {
        $("#"+progressTargets[$(this).attr("id")]+' .progress div').each(function () {
            var display = $(this),
            currentValue = parseInt(display.text()),
            nextValue = $(this).attr('data-values'),
            diff = nextValue - currentValue,
            step = (0 < diff ? 1 : -1);
            if (nextValue == '0') {
                $(display).css('padding', '0');
            } else {
                $(display).css('color', '#fff').animate({
                    'width': nextValue + '%'
                }, 'slow');
            }
            for (var i = 0; i < Math.abs(diff); ++i) {
                setTimeout(function () {
                    currentValue += step
                    display.html(currentValue + '%');
                }, 20 * i);
            }
        });
    });
    

    尝试使用数组来定位相关的进度条。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-13
      • 1970-01-01
      • 2021-07-16
      • 2014-10-17
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      相关资源
      最近更新 更多