v2p
v2p

Reputation: 659

how to correctly write plugins for jquery

for me need some tips about how to correctly write plugins for jquery.

I began to study this question from the official website JQuery http://learn.jquery.com/plugins/basic-plugin-creation/

And I decided to write your own sticky header plug-in (I know that the Internet is full of various examples, I just need tips on writing functions)

And so. I wrote a simple function that works fine.

function stickynav(el) {

        $(window).scroll(function () {
            if ( $(window).scrollTop() > 0 ) {
                $(el).css({position: 'fixed', top: '0px'});
                $(el).stop().animate({height : '40px',lineHeight : '40px'}, 200);
            } else {
                $(el).css({position: 'static'});
                $(el).stop().animate({height : '80px',lineHeight : '80px'}, 200);
            }

});

stickynav('nav');

After I decided to try to write the same function but with the advice of the JQuery team.

(function($){
  $.fn.stickynav = function(options){
    settings = $.extend({
      topSpacing: 0,
      initialHeight: '80px',
      resHeight: '40px'
    }, options);

    var $window = $(window)

    var scrolling = function(){
    $window.scroll(function(){
        if( $window.scrollTop() > settings.topSpacing ) {
            $(this).css({position: 'fixed', top: '0px'});
            $(this).stop().animate({height : settings.resHeight}, 200);
        } else {
            $(this).css({position: 'static'});
            $(this).stop().animate({height : settings.initialHeight}, 200);
        }
    });
    };
    return this.each(scrolling); 
 };
})(jQuery);

$('nav').stickynav();

And the result was a bit confused, I did something wrong.

Please help and if not it is difficult to explain changes.

Upvotes: 1

Views: 162

Answers (1)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 195982

The major problem i see is that inside the $window.scroll function you use this.
But this refers to the window in that context..

You will need to store a reference to the nav element and use that instead of this.

So the whole var scrolling = ... should become

var scrolling = function(){
    var self = $(this);
    $window.scroll(function(){
        if( $window.scrollTop() > settings.topSpacing ) {
            self.css({position: 'fixed', top: '0px'});
            self.animate({height : settings.resHeight}, 200);
        } else {
            self.css({position: 'static'});
            self.animate({height : settings.initialHeight}, 200);
        }
    });
};

An additional improvement would be to store the current state of the fixed nav, so that you do not do the animation on each scroll but only when you want to change the state..

Demo code at http://jsfiddle.net/gaby/ALDjx/2/

var scrolling = function () {
        var self = $(this);
        self.data('stickyState', false);

        $window.scroll(function () {
            var state = self.data('stickyState'),
                shouldBeFixed = $window.scrollTop() > settings.topSpacing;

            if (!state && shouldBeFixed) {
                self.css({
                    position: 'fixed',
                    top: '0px'
                }).animate({
                    height: settings.resHeight
                }, 200);
                self.data('stickyState', true);
            } else if (state && !shouldBeFixed) {
                self.css({
                    position: 'static'
                }).animate({
                    height: settings.initialHeight
                }, 200);
                self.data('stickyState', false);
            }
        });
    };

Upvotes: 2

Related Questions