Search code examples
jquerycallbackchaining

$.fn.plugin with chaining and callback


I have written a Jquery plugin called mass. I learned that it chains nicely by putting 'return this' right at the end.

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

but how can I give it a callback without hurting the chaining?

the code would look like:

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

My plugin might as well just be shown as to save confusion and extra irrelevant code:

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

I am not sure after reading examples if I have the correct understanding. If you .call() the callback then how do you go back into the original function to 'return this' to the chain or how do you pass this to the callback callback(this) and tell it to 'return this' when done?

I am missing something here? I think callback(this) is the way to go but, I don't want to have to write return this inside every time like so:

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

Solution

  • Try

    $(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/

    See

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

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