jQuery Drop Shadow Plugin Revisited

In one of my previous posts, I had shown how to create jQuery drop shadow plugin. To create the drop shadow effect, I was basically creating a div behind the elements which were to be shadowed. I knew about CSS3 box-shadow property but I did not consider it for the drop shadow effect because CSS3 is only supported by modern standard-compliant browsers but a comment of C-King at my previous post made me rethink about it and in this post, the plugin has been modified to create the CSS3 drop shadow effect.

The plugin now applies CSS3 drop shadow effect for the browsers that support it or it will use div-based approach like it did before. The plugin now checks if the current browser supports CSS3 and if so, it will apply CSS3 drop shadow effect and if CSS3 is not supported, it will apply div-based drop shadow effect. A new blur option has been added into updated plugin which is only applicable if current browser supports CSS3.

The plugin has been checked working fine in IE6+, FF, Webkit and Opera.

Download Drop Shadow Plugin (Updated)

Creating Drop Shadow jQuery Plugin

In this article, we are going to create a very useful jquery plugin, the Drop Shadow plugin. Previously, I had written an article on how to create the drop shadow effect and today we will use that code and convert it into a plugin. Here is the code we were using previously to apply the drop shadow effect to elements having shadow class:

$(window).load(function(){
	$('.shadow').each(function(){
	  $('</pre></pre>
<div>').appendTo($('body')).css({</div>
<pre>
<pre>
		position: 'absolute',
		width: $(this).width() + 'px',
		height: $(this).height() + 'px',
		backgroundColor: '#DFDFDF',
		zIndex: -5000,
		top: ($(this).offset().top + 5) + 'px',
		left: ($(this).offset().left + 5) + 'px'
	  });
	});
});

If you have been using jQuery but have never created a plugin before, you may ask why create a plugin at all. Well, there are some good reasons why not create a plugin.

How to Create a Plugin

First of all, we should make sure that we name our plugin as per standards, a jquery plugin should be named like:

jquery-pluginName-plugin.js

And since our plugin is going to be used for dropping shadows on elements, it should be named:

jquery.dropshadow.plugin.js

Now creating a jquery plugin isn’t a much of problem, the creators of jquery have made things really easy for us to create the plugins. In fact, creating a jquery plugin is as easy as:

$.fn.pluginName = function(){
   // code here....
}

However, there do exist quit some variations on the structure of the jquery plugin. For our purpose, we will stick to famous jQuery Plugin Development Pattern. Following that pattern, I have created this plugin template to create jquery plugins:

/**
 * Your plugin name and a small description
 * Author: Name here
 * Version: 1.00
 */

(function($){

    $.fn.pluginName = function(settings){

  	// Extend our default options with those provided.
  	// Note that the first arg to extend is an empty object -
	// this is to keep from overriding our "defaults" object.

        var opts = $.extend({}, $.fn.pluginName.defaults, settings);

        return this.each(function(settings){
           var options = $.extend({}, opts, $(this).data());

           var $this = $(this);

            // do something

        });
    }

  // plugin defaults - added as a property on our plugin function
  $.fn.pluginName.defaults = {
    option_name: value
  }

})(jQuery);

No need to worry about above snippet of code if you are seeing that for the first time, I will try to explain it. First of all, we wrap the jquery namespace $ in a function and create a closure:

(function($){
  // code here......
})(jQuery);

This ensures that our plugin won’t break if there are other javascript libraries used on a page where our plugin is used. This happens because in some other javascript libraries, $ has also a special meaning like in jquery. Then as I said earlier, we create a jquery plugin something like:

$.fn.pluginName = function(){
   // code here....
}

If we want to add additional settings to our plugin that will be customizable by those who use our plugins, we pass a options/settings parameter like this:

$.fn.pluginName = function(settings){
   // code here....
}

This is useful in our case because our drop shadow plugin will allow plugin users to set these settings when using the plugin:

  • shadowColor
  • shadowLayer
  • distance

Then we see following line in the template above:

var opts = $.extend({}, $.fn.pluginName.defaults, settings);

It allows plugins users to override the default plugin settigns with their own.

jQuery has an excellent mechanism of chaining which allows you to use more than one functions/methods on given wrapped set/elements, for example:

$('selector').removeClass('class-name').addClass('class-name');

And in order to add this chaining capability to our plugin, we need to put our code like this as can be seen in the template above:

return this.each(function(){
    // code here....
});

But for the sake of plugin development pattern, I pointed out earlier, it should be modified like:

return this.each(function(settings){
   var options = $.extend({}, opts, $(this).data());
});

And finally, we should put some of our default settings for the plugin:

  // plugin defaults - added as a property on our plugin function
  $.fn.pluginName.defaults = {
    option_name: value
  }

The Drop Shadow Plugin

Now that we have seen some of the details about jquery plugin development, let’s create our drop shadow plugin. First we start off with basic skeleton of plugin as shown in the template above:

(function($){

    $.fn.dropshadow = function(settings){
        // Extend default settings
        var opts = $.extend({}, $.fn.dropshadow.defaults, settings);

        return this.each(function(settings){
           var options = $.extend({}, opts, $(this).data());
           var $this = $(this);

           //////////////////////////////////////////////
           //  plugin logic code here
           //////////////////////////////////////////////

        });
    }

   // set default option values
  $.fn.dropshadow.defaults = {
	shadowColor: '#DFDFDF',
	shadowLayer: -1,
	distance:'5px'
  }

})(jQuery);

As can be seen, everything is similar to template above except for plugin name and default options for our plugin shown at the end of the above code. We now need to move our previous code we had used to create the effect in the area where it says plugin logic code here. So here is the entire drop shadow plugin code:

(function($){

    $.fn.dropshadow = function(settings){
        // Extend default settings
        var opts = $.extend({}, $.fn.dropshadow.defaults, settings);

        return this.each(function(settings){
           var options = $.extend({}, opts, $(this).data());
           var $this = $(this);

		  $('</pre></pre>
<div class="drop_shadow_layer">').appendTo($('body')).css({</div>
<pre>
<pre>
			position: 'absolute',
			width: $this.width() + 'px',
			height: $this.height() + 'px',
			backgroundColor: options.shadowColor,
			zIndex: options.shadowLayer,
			top: ($this.offset().top + parseInt(options.distance, 10)) + 'px',
			left: ($this.offset().left + parseInt(options.distance, 10)) + 'px'
		  });
        });
    }

   // set default option values
  $.fn.dropshadow.defaults = {
	shadowColor: '#DFDFDF',
	shadowLayer: -1,
	distance:'5px'
  }

})(jQuery);

This time, the only change we made to our code is that of using option properties that we allow users to specify.

Using the Drop Shadow Plugin

Using the plugin as easy as this one line of code (that’s beauty of a plugin):

$('.shadow').dropshadow();

And since our plugin allows some settings, you can specify them like:

  $('.shadow').dropshadow({
	shadowColor: '#cccccc',
	shadowLayer: -100,
	distance:'6px'
  });

This will apply the shadow to any element that has the shadow class. Of course, you can change the selector there and/or specify a single element based on id instead of a class. You can change the class name there of course based on your elements class name.

Please note that if you are going to apply the shadow to images, you need to make sure that you wrap the code in window’s load event rather than ready handler of jQuery because getting image dimensions doesn’t work in some browsers when using the ready handler. Also, we use resize event to re-draw the shadow elements when window is resized. All the divs created for shadow effect have the class drop_shadow_layer.

$(window).bind('load resize', function(e){
   if (e.type === 'resize'){
     $('.drop_shadow_layer').remove();
   }

   $('.shadow').dropshadow({
      shadowColor: '#cccccc',
      shadowLayer: -100,
      distance:'6px'
   });
});

So that will apply drop shadow effect to any element having shadow class.

I tried to make things as easy as possible and I hope you learned something useful .

Download Drop Shadow Plugin