RSS 2.0 Feed

Spinner – A jQuery Preloader Plugin

About

Spinner provides a simple approach for adding and removing a preloader for your web applications. Usage is as simple as calling $(‘elem’).spinner() and subsequently $(‘elem’).spinner(‘remove’). You may create your own custom preloaders at http://www.ajaxload.info. Please note that if you use a custom preloader, you must pass in the new height and width as options.

Configuration Options

Spinner has a short list of customizable options to give you the flexibility you need. Please visit the usage page for examples of how to use these options properly.

Option Description Default Value
img The relative path to the preloader image to be used. You may create a custom preloader image at ajaxload.info. If you use a custom preloader, you must update the height and width options to match the new image size. spinner.gif
position The position to display the spinner relative to the parent element. Options are left, center, and right. right
height The height of the preloader image. Used in calculating the vertical positioning. Must be an integer. 16
width The width of the preloader image. Used in calculating the horizontal positioning. Must be an integer. 16
zIndex The z-index of the preloader image. Useful when you have other absolutely positioned elements on the page with varying z-index values. Must be an integer. 1001
hide Determines whether the element that triggered the preloaded image should be hidden or not. If true, the element is hidden using CSS visibility as to preserve your current site layout. The element is displayed again upon closing the spinner with $(‘yourElem’).spinner(‘remove’);. Must be a boolean value (true/false). false
onStart A user defined custom callback function that is triggered before displaying the preloader. function() { }
onFinish A user defined custom callback function that is triggered when a user removes a spinner using$(‘yourElem’).spinner(‘remove’);. Occurs after the spinner has been removed. function() { }

Example Usage

The following 4 examples demonstrate Spinner usage in a nutshell.

Click here to view the examples in action.

Example 1

The spinner is displayed to the right of the clicked element for 5 seconds.

$('#example1').click(function() {
        var $this = $(this);
        $this.spinner();
        setTimeout(function() {
                $this.spinner('remove');
        }, 5000);
        return false;
});
        

Example 2

The spinner is displayed centered over the clicked element for 5 seconds and the element is hidden using visibility to maintain layout positioning.

$('#example2').click(function() {
        var $this = $(this);
        var opts = { position: 'center', hide: true };
        $this.spinner(opts);
        setTimeout(function() {
                $this.spinner('remove');
        }, 5000);
        return false;
});
        

Example 3

The spinner is displayed to the left of multiple items that have a matching class for 2 seconds.

$('#example3').click(function() {
        var $this = $('.example3');
        var opts = { position: 'left' };
        $this.spinner(opts);
        setTimeout(function() {
                $this.spinner('remove');
        }, 2000);
        return false;
});
        

Example 4

A large, non-default preloader is used which means we need to override the options for img, height, and width. The spinner is displayed to the right of the url and both onStart and onFinish callback options are used. The callbacks simply alert you in this case as an example.

$('#example4').click(function() {
        var $this = $(this);
        var opts = {
                img: 'spinner-large.gif',
                height: 48,
                width: 48,
                onStart: function() { alert('onStart callback alert'); },
                onFinish: function() { alert('onFinish callback alert, 2 seconds are up.'); }
        };
        $this.spinner(opts);
        setTimeout(function() {
                $this.spinner('remove');
        }, 2000);
        return false;
});
        

Downloads

Downloads are currently available from the following sources:

Support

If you are having issues with Spinner you may post a comment below or submit a bug report on the official jQuery plugin homepage.

Suggestions and feature requests are also welcome.

Change Log

Spinner 1.0.0

  • Initial release on 05/14/10
  • HackerNews
  • Reddit
  • Slashdot
  • Facebook
  • LinkedIn
  • del.icio.us
  • Digg
  • StumbleUpon
  • Twitter
Comments 25 comments

25 Responses

  1. fenderflip says:

    Fixed, here’s what I came up with:

    $(function spinner() {
    // example 1
    $('#toggleView').click(function() {
    var $this = $(this);
    var opts = { position: 'center', hide: true };
    $this.spinner(opts);
    setTimeout(function() {
    $(".hidden").toggle();
    $this.spinner('remove');
    }, 2000);
    });
    });

  2. fenderflip says:

    Hi, I’m getting the loader to work, but it’s running after the process that it’s pre-loading instead of during the process.


    Number View
    Item View
    Toggle View

    $("button").click(function viewToggle() {
    $('#toggleView').click(function() {
    var $this = $(this);
    var opts = { position: 'center', hide: true };
    $this.spinner(opts);
    setTimeout(function() {
    $this.spinner('remove');
    }, 2000);

    $(".hidden").toggle();
    });
    });

    I want the loader to animate while the .hidden elements are displaying, but it keeps animating after they’ve loaded. Thanks.

  3. Nice one! But I prefer the .hide() instead of remove – this way you do not have to re-create the element

    1. Corey Ballou says:

      Definitely a possibility, but there are also a few downsides. There would need to be some additional checks and an increase to the LOC due to the need to check for differences in config options and updating the existing element. It’s a tough call whether adding additional complexity is worth it. I’d have to find out how common it is for someone to use a spinner multiple times on a page.

  4. Brownieboy says:

    Strange things happen if you attempt to remove a spinner from an element that doesn’t actually have one attached at that point: the code will carry on and add a new one!

    I’ve stopped this by adding an else {return} after the if (typeof $s != ‘undefined’) line in the removal handling code. I.e.

    if (options == ‘remove’ || options == ‘close’) {
    var $s = $this.data(‘spinner’);
    var o = $this.data(‘opts’);
    if (typeof $s != ‘undefined’) {
    $s.remove();
    $this.removeData(‘spinner’).removeData(‘opts’);
    if (o.hide) $this.css(‘visibility’, ‘visible’);
    o.onFinish.call(this);
    return;
    }
    else {
    return; // to handle attempt ‘remove’ on an element that doesn’t actually have a Spinner attached to it
    }
    }

  5. Gerard says:

    Hi!

    I tried to use the spinner with a button that is in a dialog box. The spinner image appears, but hidden behind the dialog box. What should I do to display the spinner near the button, on top of the dialog box?

    Thank you!

    1. Gerard says:

      I figured it out. The z-index of the dialog box was greater than the spinner’s default value.

      Great plugin ;)

  6. Todd says:

    Hi,
    Very useful except I can’t figure out how to do this:
    I have an image I’m clicking on to load a page and when you click on the image the spinner shows which is perfect. The resulting page takes a bit to load so im thinking it would be handy to show something going on while it prepares to load.

    Problem is the url to the page doesn’t work any longer when you click the image. How do I get it to still go to the page the image is linked to??

    1. Corey Ballou says:

      Hey Todd,
      In my examples I was using return false; which essentially prevents you from redirecting to a link. Simply removing this line will allow you to load your URL. Let me know if this helps.

  7. Heyo says:

    Hi, thanx for this nice plugin.

    It’s working for me, but I got some serious browser issues.

    The image is not shown in Safari and Chrome. Those damn browser bugs!%$§

    Can anyone help me out here .. or anyone having the same issues?

    Best

    Heyo

    1. Nice plugin, thanks. I’m also having trouble seeing the image in Chrome and Firefox; I see it in IE8 though. It was working at first in Chrome, but then it stopped. Not sure if it is something I am doing wrong.

  8. jvrobert says:

    Hi – very small change – can you please add a ‘return;’ statement in the ‘if (options == ‘remove’ || options == ‘close’) {‘ block when ‘if (typeof $s != ‘undefined’) {‘ is false? Otherwise if you do a .(‘remove’) on a spinner that’s not currently showing, it starts showing.

    1. Bambou says:

      +1
      moreover, the return should be outside “if (typeof $s != ‘undefined’)” statement

      // removal handling
      if (options == 'remove' || options == 'close') {
      var $s = $this.data('spinner');
      var o = $this.data('opts');
      if (typeof $s != 'undefined') {
      //
      }
      return;
      }

      An other point about offset method. As mentioned on jquery website :

      Note: jQuery does not support getting the offset coordinates of hidden elements or accounting for borders, margins, or padding set on the body element.

      So if the element is hidden in some way, the spinner will be placed based on top=0 and left=0. Most of people probably don’t want to display the spinner if the element itself is hidden, otherwise adding an option for this can be usefull

      you can test if the element is visible using :visible selector:

      if ($(this).is(':visible')) {

      }

      Thanks for this plugin
      Cheers

  9. DStone says:

    Hey,
    This is a neat plugin, but I’m trying to get it to work with (fairly quick) AJAX calls of varying length, such that a setTimeout doesn’t seem to be the best solution. However, I’m pretty sure the spinner never shows up on my website is because the webpage never regains control to display the spinner before the AJAX call is done. Any suggestions?

    1. LoRd says:

      @DStone: so you could use Jquerys “beforeSend” and “success”

      I used it like that (just a small example):

      $.ajax({
      	type: "POST",
      	dataType: "json",
      	url: "myFile.php",
      	data: jQuery.param($('formular')),
      	beforeSend: function(data){
      		$this.spinner();
      	},
      	success: function(data){
      		$this.spinner('remove');
      	}
      });
      
      1. Corey Ballou says:

        Also, just to be safe, you might want to add $this.spinner('remove'); to the error callback function.

  10. Ed says:

    Hi there

    Any hints on how to use this on a submit button?

    I can get the code working but the button does not submit!

    Many thanks

    1. Corey Ballou says:

      Hey Ed,

      The default handling of Salid is to bind your actual form, i.e. $('form').salidate(options). If you take a look at the source code of the plugin, you’ll notice that Salid binds the target element to the submit event. If errors occur, the form will not be submitted due to handleErrors() function returning false. If no errors occur, the function should return true and the form submission should occur.

      If you have Firefox, I highly suggest you take a look at installing the Firebug plugin and turning it on when you are testing JavaScript code as it might be a quick indication of any errors occurring. Once you’ve got Firebug enabled, you’ll want to open it up and ensure the console tab is turned on.

      Let me know if this clears up anything for you, if not I’ll need to see your code to debug.

    2. Ed says:

      Hi there Corey

      Thanks – I managed to get it working OK. It now displays a spinner when initiating a select, although I am hoping to modify this to spin until the select has completed (form submitted).

      For example I select the page “About the pentium III” from a dropdown and wish the spinner to continue until the (page load event?) of the selected page.

      I am using a onchange in the select to submit the form.

      I appreciate the code – this was actually very simple to use (firebug told me where my previous problem was… simply pointing to the wrong path to your .js!)

      Thanks
      Ed

  11. Hey, you can check out a great jQuery Preloader that I wrote with full callbacks, auto reading of images to preload, and a lot of easing in animations. Check it out here: jQuery Preloader

  12. jshdjsdj says:

    good sample of the plugin

  13. jQueryNewBie says:

    I think your example would have been great, if you could change the image to make it appear more aesthetic rather than poor gif graphic (I presume it to be gif, don’t feel like going back to check it :)).

    1. cballou says:

      Point taken. I’ll swap out the default example image this week to something more suitable. Sometimes us developers get caught up in simply providing functionality with minimal consideration for aesthetics. I’ve definitely got to improve my examples a bit.

Leave a Reply

Allowable tags
a, abbr, b, blockquote, cite, code, em, i, strike, strong, pre lang, line

* comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.