문제

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!

도움이 되었습니까?

해결책

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/

다른 팁

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top