zomgistania

Main page | About | Articles | Previous Posts | Archives

Saturday, July 15, 2006

Object-oriented JavaScript

I'm working on a "World Clocks" widget for Opera 9. It's basically something which can display multiple clocks set in different timezones.

As the widgets in Opera 9 are coded with HTML and the like, the actual funcionality is written in JavaScript. Therefore I was thinking about a way to implement the different clocks and thought about making it a class.

Classes in JavaScript are a thing many don't know of, so I'll write an introduction to them, based on the Clock class I made.


The idea

The idea is to make a Clock class... as we're going to have one or more of them, the time can be taken from a "central location", this time a JavaScript Date object.
Because of this, the Clock itself will not store a time, it will just format the time based on it's settings.

Things we're going to store in the clock for starters: Clock's name/id and the clock's offset from GMT +0. It should also have functions for returning the HTML-element for the clock and updating it's element in the document.


Let's begin!

Creating a class in JavaScript is actually a function definition:


function Clock(name,timeOffset)
{

}



Now we need to add the variables for storing the name and the offset.
To add member variables to the class, the following syntax is used:

function Clock(name,timeOffset)
{
this.name = name;
this.offset = timeOffset;
}


The values required by the Clock function are set to the member variables.
Adding functions to the class works in a very similar fashion:

function Clock(name,timeOffset)
{
this.name = name;
this.offset = timeOffset;

this.Tick = function(time)
{
var h = time.getUTCHours();
var m = time.getUTCMinutes();
var s = time.getUTCSeconds();

if(m < 10) m = '0'+m;
if(s < 10) s = '0'+s;

h = Number(h) + Number(this.offset);
if(h > 23) h -= 24;
if(h < 0) h += 24;

var obj = document.getElementById(name+'_time');
obj.innerHTML = h+':'+m+':'+s;
}

this.GetElement = function()
{
var base = document.createElement('div');
base.id = name;
base.className = 'clock';

var label = document.createElement('h2');
label.id = name+'_label';
label.className = 'label';
label.innerHTML = name;

base.appendChild(label);

var time = document.createElement('span');
time.id = name+'_time';
time.className = 'time';
time.innerHTML = '00:00:00';

base.appendChild(time);

return base;
}
}


Firstly, there's the Tick function. It takes a JavaScript time object as it's parameter.
From the time object we take three values: the UTC hour, UTC minutes and UTC seconds. Then we check whether the minutes or seconds are smaller than 10 and add a zero to the front to make them appear nicer in the formatting.

As UTC equals GMT +0, we just add the GMT offset to the UTC hours to get the time in the desired timezone. Now, if the clock was 23:00 GMT+0 and we added there, say, 6 hours, the clock would obviously show something completely wrong... 29:00 isn't a proper time as you might know. That's why the next thing we do is check whether the time goes out of bounds and add or remove 24 hours for making it correct again.

The the code just gets the element for the clock and sets it to show the time.


Then the GetElement function..
First, we create an empty div element to hold the clock. We give the clocks name for the div as it's ID and set it's CSS class name to 'clock'. Then we create a h2 element for displaying the clock's name. Again we set the id and CSS class name and also the innerHTML is changed to the clocks name. After this, we append the h2 element to the div we created first.
Finally we create a span for displaying the actual time for the clock and add that too to the div. Finally we return the whole div object.



Finally...

Using this class would be simple as this:

//create a new clock
var myclock = new Clock('example',3);

//add the clock's element to the document
document.body.appendChild(myclock.GetElement());

//Update the clock once with the current time
myclock.Tick(new Date());


So there we have the Clock class. There's a bunch of things which could be added, like storing a daylight savings time, so the clock would automatically stay in the proper time in case of DST. Also, the Tick function could check if the passed variable is actually a Date object or not and it could also allow the user to format the time in 12-hour format instead of 24-hour.



In case you want to check out the widget I'm working on, you can download it from Opera Widgets.

Some intresting reading on JavaScript can be found at "JavaScript: the worlds most misunderstood programming language"

6 Comments:

  • Are there any access level modifiers like public, private or such like you see in C++?

    By Anonymous Anonymous, at 2:29 PM  

  • Yeah it's actually possible...

    if you define a variable inside the class like this, it becomes private:

    var privateVar = someting;

    and if you define a function inside the class like this:

    function privateFunc() {
    /* ... */
    }

    By Blogger Jani, at 2:42 PM  

  • How about a screenshot? :)

    By Anonymous Anonymous, at 12:56 AM  

  • I updated the link to the widget, actually a while ago already.. there's a screenshot at the Opera Widgets page that is now linked.

    By Blogger Jani, at 10:22 PM  

  • Nice Blog !

    Interesting, fast paced and clear ...
    its so hard to find this these days :)

    By Anonymous Anonymous, at 3:47 PM  

  • Thanks for the nice words, I do my best :)

    By Blogger Jani, at 5:31 AM  

Post a Comment

<< Home