Member Sign In
Not a member?

A Wired.com user account lets you create, edit and comment on Webmonkey articles. You will also be able to contribute to the Wired How-To Wiki and comment on news stories at Wired.com.


It's fast and free.

Webmonkey is a property of Wired Digital.
processing...
Join Webmonkey

Please send me occasional e-mail updates about new features and special offers from Wired/Webmonkey.
Yes No

Please send occasional e-mail offers from Wired/Webmonkey affiliated web sites and publications, and carefully selected companies.
Yes No

I understand and agree that registration on or use of this site constitutes agreement to Webmonkey's User Agreement and Privacy Policy.
Webmonkey is a property of Wired Digital.
processing...

Retrieve Sign In

Please enter your e-mail address or username below. Your username and password will be sent to the e-mail address you provided us.

or
Webmonkey is a property of Wired Digital.
processing...

Welcome to Webmonkey

A private profile page has been created for you.
As a member of Webmonkey, you can now:
  • edit articles
  • add to the code library
  • design and write a tutorial
  • comment on any Webmonkey article
Close
Webmonkey is a property of Wired Digital.

Sign In Information Sent

An e-mail has been sent to the e-mail address registered in this account.
If you cannot find it in your in-box, please check your bulk or junk folders.
Sign In
Webmonkey is a property of Wired Digital.

Write Widget-oriented JQuery Apps with Classes

/skill level/
/viewed/
0 Times

Contents

Introduction

Some days ago, Jeff Watkins published his [Coherent JS] framework: it is an outstanding new framework which implements Apple Bindings in Javascript. From his first tutorial I got the inspiration to write this article: it could be nice to structure our JQuery apps in widgets, using fast and reusable classes.

What you'll need

You need a text editor, latest JQuery, and boom! =)

Page structure

Think about your page as a set of tools: it's easy to see every part of the page as a widget with its own behaviour attached.

MVC: start building your model

Simply write you XHTML + CSS code, describing your page parts.

For example, if I want to make an image to move (stupid example, I know, but easy to implement and to understand for you ^^) creating a widget I've got to write the following code:

<img id="myImage" src="images/myimage.png" alt="Moving image" />

Separate Code from Presentation

In the head section of my page I'm going to write:

<script src="js/jquery-1.2.5.pack.js" type="text/javascript" charset="utf-8"></script>
<script src="js/ImageWidget.js" type="text/javascript" charset="utf-8"></script>
<script src="js/Main.js" type="text/javascript" charset="utf-8"></script>
  • js/jquery-1.2.5.pack.js is the latest JQuery available today.
  • js/ImageWidget.js will be our Widget class.
  • js/Main.js will be our initialization class.

Write a Class

We are going to use a particular kind of class pattern, which gives the possibility to have private variables (differently from many plugins and patterns) and reduces the overhead of public functions (differently from the GREAT Module Pattern). That's it:

var MyClass = function(args) {
	if (!(this instanceof MyClass)) return new MyClass(args); //prevent the call without 'new' construct
	
	var myPrivateVar = args.MyPrivateVar;
	this.myPrivateVar = function() { //getter
		return myPrivateVar;
	}
	this.setMyPrivateVar = function(value) { //setter
		myPrivateVar = value;
	}
	
	this.publicVar = "My public value";
};

MyClass.prototype.myPublicFunction = function() {
	// code ...
};

MyClass.prototype.myStaticVar = "I'm static here";

Write a Widget Class

In a Widget it's important to store the DOM Object which represents the Widget: so pass it to class constructor like this:

var ImageWidget = function(object, args) {
	if (!(this instanceof ImageWidget)) return new ImageWidget(object, args); //prevent the call without 'new' construct
	
	this.object = function() { //returns attached object, the object which is controlled from this class
		return $(object);
	};
...
...
...

That's great because you can use this.object() getter everywhere in your code.

So, let's implement the animation:

ImageWidget.prototype.move = function(duration) {
	var self = this; //use the closure!!!
	
	this.object().animate({
		left: "+= 200px"
	}, {
		duration: duration,
		complete: function() {
			// you can use the closure and call class functions with self.myFunct()
		}
	});
};

Event delegation

To control all DOM events in your widget you could start observing the DOM in the constructor, delegating one the class to handle all the callbacks.That's possible thanks to bubbling: when an event is triggered, it bubbles towards the top of the DOM tree. For exampe if I have and Image Widget (so, an image, a caption and two navigation buttons - next, prev) you will attach the div to a class and, here, you will observe clicks to contained elements.

//Event delegation in an Image Widget
this.object().bind("click", {self: this}, function(event) {
	var tgt = $(event.target); //where event has effectively been triggered
	var self = event.data.self;
	
	if ("next" == tgt.attr("id")) {
		// next button pressed
	}
	else if ("prev" == tgt.attr("id")) {
		// prev button pressed
	}
});

Event propagation permits to structure our JavaScript in a different way, [triggering custom events] and binding them everywhere in the page.

Attaching the Class to Widget: giving a behaviour to our static DOM Objects

And the Main.js??? Here we are! =D

$(function() {
	var myWidget = new ImageWidget("#myImage", { }); //no args in this stupid example!
	myWidget.move(3000); //3 seconds
});

It initializes and fires methods as DOM is loaded.

Steps

Alternate methods

Thousands...

Suggested readings

Google "Coherent JS", "John Resig", "JQuery", "Low Pro", ...

  • This page was last modified 14:32, 25 May 2008.
Edit this article
Reddit Digg
 

/related_articles/

See more related articles

Subscribe now

Special Offer For Webmonkey Users

WIRED magazine:
The first word on how technology is changing our world.

Subscribe for just $10 a year