Friday, 4 January 2013

So I went ahead and wrote you a plugin.

If you know me at all you will know that I don't often suggest or use third party libraries for Javascript. Not because I think i'm too good for them or anything, I just enjoy understanding my own code and being able to debug with some degree of certainty.
With this said; I created a very simple plugin that provides the 'Return to Top' buttons you see on so many pages. Introducing: mcToppy.jquery.js (If you can think of a better name, by all means tell me!).

$.mcToppy function(options{
    var btn $('<button></button>'),
        defaults {
            css{
                position'fixed',
                bottom'16px',
                right'16px',
                backgroundColor'#FFF',
                color'#444',
                padding'4px 6px',
                borderRadius'4px',
                display'none'
            },
            text'Top',
            speed500,
            callbackundefined
        };
    options options || {};
    options $.extend({}defaultsoptions);
    btn.css(options.css).text(options.text).on('click'handle_click).appendTo('body');
    $(window).on('scroll'handle_scroll);

    function handle_scroll({
        if ($(this).scrollTop(!= 0{
            btn.fadeIn('fast');
            return;
        }
        btn.fadeOut('fast');
    }


    function handle_click({
        $('html,body').animate({
            scrollTop0
        }options.speed).promise().done(options.callback);
    }


};
$.mcToppy();

The plugin is self explanatory for the most part (I hope), but let me try to walk you through how to write this and why:
The Plugin: There are two basic forms of a jQuery plugin. One actions on the elements returned from the selector, the second is just a method attached to the $ namespace. Because we are not associating this with an HTML Element on the page we will choose the latter and attach directly to the jQuery ($) namespace.

$.mcToppy function(options{

The Button: There needs to be an element for the user to click. For this script I choose to use a button. For ease of use create this by passing the button as an HTML string to the jQuery selector. The library will return a jQuery object containing the HTML Element for the button.

var btn $('<button></button>')

The Defaults: We like customization right? Well there needs to be some defaults to customize! Here they are defined in a semantic way. The CSS is defined in it's own object which can later be directly passed to the .css() jQuery function. The text, speed, and callbacks all are for exactly what their name implies: Text is the button text, speed determines the time taken to return to the top, and the callback is invoked after the script has completed (you are at the top of the page).

defaults {
    css{
        position'fixed',
        bottom'16px',
        right'16px',
        backgroundColor'#FFF',
        color'#444',
        padding'4px 6px',
        borderRadius'4px',
        display'none'
    },
    text'Top',
    speed500,
    callbackundefined
};

Extending the defaults and building the button: Merging the options and the defaults is important. This allows the user to set up some but not all of the options and still fall back on the defaults provided. To accomplish this use the jQuery.extend() function. Pass in an empty object, then the defaults, then the options. The options will over write the defaults where applicable then the entire thing will be pushed to a new object (first argument) and returned. After that the options need to be applied to the button and the button needs to be appended to the body.

options options || {}; // if nothing is passed in
options $.extend({}defaultsoptions);
btn.css(options.css).text(options.text).on('click'handle_click).appendTo('body');

Handling the scroll and click events: Using the .on() method listen for 'scroll' on the window object. When the user scrolls check to see if they are at the top or not and action accordingly. When the user clicks on the button we want the page to scroll back upto the top. Using .animate() here will allow this scroll to be seen over a time delay and not just 'jump' back to the top. Like mentioned above we need to wait for both animations to complete before calling the callback function. To achieve this we use jQuery's .promise().

$(window).on('scroll'handle_scroll);
function handle_scroll({
    if ($(this).scrollTop(!= 0{
        btn.fadeIn('fast');
        return;
    }
    btn.fadeOut('fast');
}


function handle_click({
    $('html,body').animate({
        scrollTop0
    }options.speed).promise().done(options.callback);
}


And there you have it! Want to see a demo? Click on the 'Result' tab and scroll down a bit.


You can Fork or download the source code for the plugin from https://gist.github.com/4453414
Enjoy!

No comments:

Post a Comment