5

How would i go about passing the context of $(this) to a plugin?

Currently, i have a plugin(code as shown below)

(function($) {
  $.fn.slides={
    slideIn:function(){
      $(this).fadeIn().slideDown();
    },
    slideOut:function(){
      $(this).fadeOut().slideUp();
    }
  }
})(jQuery);

Whenthe plugin is called via

$('h1').click(function(){
  $(this).slides.slideOut();
});

i get an error

Uncaught TypeError: Cannot read property 'defaultView' of undefined

because the context of this, is not passed correctly to the plugin's slideOut() method.I.e the slideOut's this context is that of the object $.fn.slides.

Apart from using .call() to pass the context,i.e

$('h1').click(function(){
  $(this).slides.slideOut.call(this);
});

is there any other way to pass the this context correctly to slideOut(), or anyway to structure my plugin so that i can call the method slideOut() via

 $('h1').click(function(){
      $(this).slides.slideOut();
    });

?

Thanks!

Kenneth .J
  • 1,433
  • 8
  • 27
  • 49

4 Answers4

2

I understand you might want to not polute the jquery names-space by attaching both functions to a single slides member, but I think you're better serving the audience by creating 2 separate plugins.

Also, your plugins need to return $(this) so that they're chainable:

$.fn.slideIn = function(){

    var $this = $(this);
    $this.fadeIn().slideDown();
    return $this 
};

$.fn.slideOut = function(){

    var $this = $(this);
    $this.fadeOut().slideUp();
    return $this 
}

Then (for example):

$('h1').click(function(){
    $(this).slideOut();
});
Faust
  • 15,130
  • 9
  • 54
  • 111
2

Something like this would look more like a jQuery plugin:

(function ($) {
    $.fn.slides = function(method) {

        var methods = {
            slideIn: function () {
                $(this).fadeIn().slideDown();
            },
            slideOut: function () {
                $(this).fadeOut().slideUp();
            }
        };

        return this.each(function() {
            methods[method].call(this);
        });
    };
})(jQuery);

Usage:

$('h1').click(function() {
    $(this).slides('slideOut');
});

Also note that jQuery plugin should return a jQuery instance collection to make chainable possible.

Demo: http://jsfiddle.net/cC8fF/

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • What does the line methods[method].call(this) do? specifically, what does the method in the square brackets do? Also, why does .call(this) work? Shouldnt the context be that of the object(i.e same problem as my code above) and not $('h1')? – Kenneth .J Apr 18 '14 at 05:42
  • 2
    object["property"] is the same thing as object.property. So if you called slides('slideOut') in the example above, it would call methods.slideOut. .call(this) will call .slideOut and set this to the same context that we're in right now, instead of setting this to methods. – Josef Engelfrost Apr 18 '14 at 06:35
0

You can do like below code and go and check demo :-

(function($) {
  $.fn.slides={
    slideIn:function(){
      $(this).fadeIn().slideDown();
    },
    slideOut:function(result){
        alert(result);
      result.fadeOut().slideUp();
    }
  }
})(jQuery);

$('h1').on("click", function(){
    alert($(this));
  $(this).slides.slideOut($(this));
});

Demo :-

http://jsfiddle.net/avmCX/32/

Neel
  • 11,625
  • 3
  • 43
  • 61
0

I tried to do something like you have mentioned above and ended up checking other links. It seems like for plugin we need to define specific function first for best practise.If we trying to prototyping that function like

myplugin.prototype.newfn =  function (){

}

Then we need execute the myplugin function first. All the details required for the best practise is in following answer :

How to create a jQuery plugin with methods?

Here is the link for useful boilerpalates of plugin : Boilerplates for plugin

and ofcourse jsfiddle for your working plugin :

 var methods = {
    slideIn:function(){

        this.fadeIn().slideDown();
        return this;
    },
    slideOut:function(){

        this.fadeOut().slideUp();
        return this;
    },
    init: function() {
        // or you can do more functions here
        return this;
    }
};

$.fn.slides = function(methodOrOptions) {

    if ( methods[methodOrOptions] ) {
        return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
        // Default to "init"
        return methods.init.apply( this, arguments );
    } else {
        $.error( 'Method ' +  methodOrOptions + ' does not exist on jQuery.slides' );
    }    
};

And you can call it like this :

 $('h1').click(function(){
  $(this).slides("slideOut");
});

slide up slide down jsfiddle

Community
  • 1
  • 1
surajRahel
  • 266
  • 1
  • 4
  • Lol i am just new to stackover flow to answer questions.But old to jQuery tho .thats y i need to edit again and again to express the right answer. – surajRahel Apr 18 '14 at 06:11