Question

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!

Was it helpful?

Solution

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/

OTHER TIPS

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();
});

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/

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top