带链接和回调的$ .fn.plugin

时间:2014-07-26 17:20:53

标签: jquery callback chaining

我编写了一个名为mass的Jquery插件。我通过在最后把“返回这个”放在正确的位置来了解它。

$('.thing').mass(0.5,500).draggable();

但是如何在不伤害链接的情况下给它回调?

代码看起来像:

$('.thing').mass(0.5,500,function(){/*do some stuff*/}).draggable();

我的插件也可能只是为了节省混淆和额外的无关代码:

$.fn.mass=function(options,callback){/*do stuff*/return this;}

如果我有正确的理解,在阅读实例后我不确定。如果你.call()回调那么你如何回到原来的函数'将此'返回到链中?或者你如何将它传递给回调回调(this)并告诉它在完成时'返回'?

我在这里遗失了什么?我认为回调(这个)是要走的路,但是,我不想每次都写回报这样:

$('.thing').mass(0.5,500,function(){/*do some stuff*/return this;}).draggable();

2 个答案:

答案 0 :(得分:1)

正如您所关注的那样,一个体面的jQuery插件应该是一个优秀的团队成员,而不是杀死链。这意味着:

  • 它应返回一个jQuery对象,以便您之后可以应用更多方法调用。
  • 它应该在匹配元素的原始集合上工作,并将其传递给下一个方法调用,可以是未更改的,也可以是适当的修改(如文档所述,并由插件功能指定)。

不做的事情:

  • 忽略匹配的元素并从头开始运行您自己的选择
  • 无理由地销毁元素集合(例如,无意中返回新的jQuery对象而不是原始的jQuery对象)。

回调函数在这里扮演什么角色?绝对没有。

虽然我不完全确定关注点是什么,但是一个常见的误解并不是区分函数引用和函数调用。例如,鉴于此功能:

function add(a, b){
    return a+b;
}

这是一个函数调用:

foo(add(3+5));

add()立即运行,返回8并将8传递给foo()。但是,这是一个函数参考:

foo(add);

add()无法运行。它只是传递给foo(),后者可以在稍后阶段决定如何处理它。

总结一下,当你做这样的事情时:

$('.thing').mass(0.5,500,function(){/*do some stuff*/}).draggable();

... /*do some stuff*/位未运​​行且对链没有任何影响。之后,您可以选择运行它,但可能在.draggable()完成其魔法之后很长时间。

答案 1 :(得分:1)

尝试

$(function() {
$.fn.plugin = function(a, b, callback) {
  // save reference to `this` as `that`
  var that = this;
  // change context of `callback` to `$(this)`
  var proxy = (callback != undefined 
              ? $.proxy(typeof callback === "function" 
                ? callback 
                : $.noop(), $(this)) 
              : $.noop());
  var a = a || null;
  var b = b || null;
  // do stuff
  $(this).append(a * b);
  console.log(a, b);
  // return `$(this)` , as `$(that)` , chainable
  return $.when(proxy()).promise($(that));
};
$("#proxy").plugin(Math.PI, 123, function() { 
   // `log` `id` of `$(this)` object , i.e., `$(this) === $(that)` ,
   // returned `deferred.promise` object 
   console.log($(this)[0].id)}) // `proxy`
   .css("color", "green");
});

jsfiddle http://jsfiddle.net/guest271314/JKrc4/

http://api.jquery.com/jQuery.proxy/

http://api.jquery.com/deferred.promise/