Home >
My first jQuery plugin
Before anyone gets excited, this is a pretty sucky plugin, but it's my first attempt to build a "real" plugin, and while the results aren't exactly pretty, I think I'm finally getting a hang on the process. My main resource for this was a blog entry I mentioned in my last jQuery FTW article: How to Developer a jQuery Plugin by Craig Buckler.
The idea I had for my plugin was a simple one. Use an image's title tag to create a caption that you could actually see. So for example, consider the following simple HTML:
<h1>Hello</h1>
<p>Simple text.</p>
<img src="rayfat.jpg" title="Raymond Fat">
<img src="raynotasfat.jpg" title="Raymond Not as Fat">
I'd like for the two images to display the title attribute on the image itself - with a nice little background so it stands out. I began by creating a new JavaScript file for my plugin wrapped in the following lines:
(function($) {
//meat will go here
})(jQuery);
This was based on Craig's advice as a simple way to assure my declarations would get added to the jQuery library. Each plugin will added using the following syntax:
$.fn.myPlugin = function(args) {
So for my plugin, I decided on the name, makeCaption, and decided I'd take one argument, color. I'd use the argument when drawing the caption. Here is my declaration:
$.fn.makeCaption = function(color) {
So far so good. Now ignoring the actual "meat" of my plugin and what it does, there are two critical pieces to your plugin code.
First - don't forget that jQuery works with selectors. In other words, "Find some crap on my page and do something to it." In this case, "crap" can refer to a single image, or it can refer to N images. Therefore my code has to keep in mind that it is being passed a collection of stuff.
The second important part is simple. When you end your code, do not forget to "return this". All jQuery code should do that to allow for chaining. My code ran fine without it because, well I just forgot, but you don't want to leave this off.
Here is an extremely simple example that demonstrates a plugin:
(function($) {
$.fn.myTest = function(){
this.each(
function(){
console.log('ran once for ' + $(this).attr("id"))
}
)
return true
}
})(jQuery);
And here is the HTML I'll use to demonstrate:
<html>
<head>
<script src="jquery/jquery.js"></script>
<script src="myplugin.js"></script>
<script>
$(document).ready(function() {
$("img.caption").myTest()
})
</script>
</head>
<body>
<h1>Hello</h1>
<p>Simple text.</p>
<img src="rayfat.jpg" title="Raymond Fat" class="caption" id="img1">
<img src="raynotasfat.jpg" title="Raymond Not as Fat" class="caption" id="img2">
</body>
</html>
So notice I've included jQuery and my plugin file as well. My plugin, myTest, is called and chained to the selector img.caption, which will find images with the caption class.
Going back to the plugin - note the use of this.each immediately. This will handle looping over everything the selector had matched. Inside of it, $(this) lets me get a jQuery wrapper around the matched object which then lets me grab the ID value. Woot. So the grand result of this is that I can use the Firebug console to show all the IDs of the matched items.
So just to repeat - I've now got a plugin. The plugin automatically loops over the items matched by the selector. I can now actually do something in this loop. What that something does is obviously dependent on what I'm trying to accomplish, but for me, the code so far is really the most important part of the entire process. The rest is just cow bell.
Let's take a look at my final plugin:
$.fn.makeCaption = function(color) {
if(color == null) color = 'yellow'
this.each(
function() {
//get title
var title = $(this).attr("title")
if(title) {
//get image props
var height = this.height;
var width = this.width;
var pos = $(this).position()
//create new dom element
//set sWidth to a % of the image's width
sWidth = .9 * width
//height is hard coded
sHeight = 20
//make the top be 5 pixels below botto of image
sTop = pos.top+height-sHeight-5
//make it centered
sLeft = ((width-sWidth)/2)+pos.left
var s = "<div style='background-color:"+color+";width:"+sWidth+"px;height:"+sHeight+"px;position:absolute;left:"+sLeft+"px;top:"+sTop+"px'>"+title+"</div>"
$(this).after(s)
//remove title
$(this).attr("title","")
}
}
)
//allow jQuery chaining
return this
}
From top to bottom, the logic is as follows:
- Get the title.
- If we don't have a title, don't do anything.
- Get the height, width, and position of our image.
- Design a caption width (sWidth) that is a percentage of the entire image. Yes, this will fail on slim images. Height is hard coded. It should be dependent on the text really.
- Position the caption close to the bottom of the image and centered.
- Create a DOM element (a div). Note that the color is based on the argument we passed in or it defaults to yellow. It's absolutely positioned, so we can just add it to the page and it will be placed correctly.
- Finally, remove the title. I'm using it as a caption already, so I figured why not?
I modified my HTML to call the plugin. Remember from the previous code block I had two images with title tags on them.
$("img.caption").makeCaption('red')
Here is the end result:
Not too terribly complex, right? Note that I did not test this on IE. My main point here was to get used to the plugin framework, so even if it is broken on IE I don't care so much.
All in all - once you kinda get the 'jQuery Plugin Way', it works pretty well. I'd love to hear some commentary on this from more experienced jQuery users. I'd also love to hear from users of other frameworks, like Ext. Do they make it this easy?





Facebook Application Development
Comments
Leave a comment