使用参数传递可选的回调函数

时间:2012-05-04 08:44:25

标签: javascript function callback

我正在尝试以不同的方式创建一个小型滚动方法,该方法可以采用可选的效果回调函数。想象一下,我可以运行scrollToEl(el,flash),它首先向下滚动到元素并闪存。我通常会怎么做?

这就是我所做的......但它并没有真正发挥作用。

scrollToEl : function(el, callback) {
    // flash the selected product
    var self = this;
    $('html, body').animate({
        scrollTop: el.offset().top - 50
    }, 1000, 'swing', callback); // how to pass el here as well paired with callback?
}

flash : function(el) {
    // flash the selected product
    el.animate({
        opacity : 0.4
    }, 100, 'swing', function() {
        el.animate({
            opacity : 1
        }, 1000, 'swing');
     });
},

我想这样用:

var el = $('#element');
scrollToEl(el, flash); // how to pass in to the callback function flash?

2 个答案:

答案 0 :(得分:3)

您可以使用闭包:

scrollToEl : function(el, callback) {
    // flash the selected product
    var self = this;

    // Get completion callback if any
    var completion;
    if (callback) {
        completion = function() {
            callback(el); // See below if you prefer `el` to be `this` in the callback
        };
    }
    else {
        completion = $.noop;
    }
    $('html, body').animate({
        scrollTop: el.offset().top - 50
    }, 1000, 'swing', completion);
}

有关闭包的更多信息:Closures are not complicated

如果您希望回调接收元素为this,则可以使用jQuery.proxy而不是您自己的包装函数:

scrollToEl : function(el, callback) {
    // flash the selected product
    var self = this;

    $('html, body').animate({
        scrollTop: el.offset().top - 50
    }, 1000, 'swing', callback ? $.proxy(callback, el) : $.noop);
}

同样的事情,因为proxy创建了一个函数。但是它没有在调用scrollToEl的上下文中引入闭包。

答案 1 :(得分:2)

回调将受影响的元素作为this而不是参数更为正常:

flash : function() {
    // flash the selected product
    $(this).animate({
        opacity : 0.4
    }, 100, 'swing', function() {
        $(this).animate({
            opacity : 1
        }, 1000, 'swing');
     });
}

然后使用一个使用.call.applyel绑定到this的闭包来调用它:

$('html, body').animate({
    scrollTop: el.offset().top - 50
}, 1000, 'swing', callback ? function() {
    callback.call(el);
} : undefined);