Friday, December 28, 2007

An Introduction to Classy Javascript

Let me first tell you the why and then I will explain the what. By using classes in Javascript, you will notice a couple immediate benefits:

  1. Custom classes make your code more reusable. If many of your applications use a similar functionality, you can define a class to help and facilitate that functionality. Now you can just use your new class in multiple projects to provide the common functionality. For example, let's say you create a custom accordion effect. If you use classes to define the effect you can use the same code to provide the same effect on another page simply by utilizing the class you created.

  2. Using classes helps to organize your code. If you are using classes, you will see that instead of just one really long piece of code, your code will become broken into smaller pieces of related methods and properties. This will make your coding easier to maintain and troubleshoot.


So what is this terrific sounding little tool and how do we use them? A class is used to define a common type of object that will be used in a given application. For example, let's say that we are creating an application to keep track of animals in a pet store. Each animal will have a name, and a species. We could do the following:





  1. var pet1 = new Object();

  2. pet1.name = 'Gabriella';

  3. pet1.species = 'Dog';

  4. var pet2 = new Object();

  5. pet2.name = 'Trudy';

  6. pet2.species = 'Bird';

  7. // and so on



As you can hopefully see, that is just going to get long and annoying very quickly. If I have twenty different pets then it takes 60 lines of code just to create the objects. There is also no good organization to this. We have no indication that pet1 and pet2 are actually the same type of object. A much better way is to declare a class.





  1. function Pet(name, species){

  2. this.name = name;

  3. this.species = species;

  4. }

  5. var pet1 = new Pet('Gabriella', 'Dog');

  6. var pet2 = new Pet('Trudy', 'Bird');



We have just created a custom Pet class. Each Pet object has two properties: a name and a species. Now we can tell at first glance that pet1 and pet2 are the same type of object, and our code instantly becomes more readable. It also takes only one line to declare an object, shortening the long code we would have had if we had created the objects each individually without a common class.

What About Methods?


We have seen how to set properties in classes, but we can also use these classes to define common methods to objects. We could do this by simply adding another line inside of our class declaration.





  1. function Pet(name, species){

  2. this.name = name;

  3. this.species = species;

  4. this.view = view;

  5. }

  6. function view(){

  7. return this.name + " is a " + this.species + "!";

  8. }

  9. var pet1 = new Pet('Gabriella', 'Dog');

  10. alert(pet1.view());



We just added a view method to any object that is a Pet. The call above would return "Gabriella is a Dog!". There is one problem here though. If we have 20 pets, each pet is carrying a view function. That may not seem like much, but as this pet store grows, and we have more and more pet objects, each with the view function, we are going to start running into memory problems.

What we should be doing here instead, is use the prototype keyword. The prototype keyword allows us to have objects inherit the method from the class they are members of. The prototype keyword is a very powerful tool, and I will go into more detail on it in a later post, but for now some basic understanding should suffice. For example, take a look at the code below:





  1. function Pet(name, species){

  2. this.name = name;

  3. this.species = species;

  4. }

  5. function view(){

  6. return this.name + " is a " + this.species + "!";

  7. }

  8. Pet.prototype.view = view;

  9. var pet1 = new Pet('Gabriella', 'Dog');

  10. alert(pet1.view());



We have now dropped the view from the initial construction of our class, saving us some memory space. Now using the prototype keyword, we have set a view method to the Pet object. Since pet1 is a member of Pet, it has access to the function. Essentially, we have created the same effect as before, only now, the view function is only stored once, instead of once for each pet object declared.

As you can see, classes are a very valuable coding tool. They help to provide organization, and help to make our code more reusable. When used in conjunction with the prototype keyword, they can be extremely powerful and provide a lot of flexibility. This article really just touched the tip of the iceberg. There is so much you can do with this combination, and I highly recommend taking a deeper look. Once you start to use prototypes and classes in your applications, you will find them indispensable and wonder how you got along without them.

Sunday, December 23, 2007

A Less Painful CSS Experience

CSS can be a tricky little fellow. It's easy to learn, but difficult to master. There are, after all, 122 CSS Level 2 Properties. Add to that pseudo-classes, selectors, inheritance, and specificity, and you have yourselves quite a bit of information to try and remember. Here are a few things that have made CSS development a little smoother for me, and hopefully they can do the same for you.

Know the common bugs


Different browsers will handle CSS differently. This is something every CSS developer learns early on, sometimes painfully. Make sure when you come across a bug you force yourself to take a few minutes to look into it and gain an understanding of what is causing the problem. You will be surprised by how few fancy CSS hacks you will have to resort to if you know how to dodge the problems in the first place.

Check your work often


After every couple rules you put into your stylesheet, you should be checking each browser you have access to so you can see what effect the rule had on the layout. The worst thing you can do, in my opinion, is to create your CSS entirely and then check it in each browser. Now you have to wade through all your CSS and try to find where the problem is coming from. However, if you are checking your work after every couple rules, you will have a pretty good idea where the problem lies, and you will be able to fix it that much more quickly.

Know your resources


This may be the most important tip here. Like I said, with so many selectors, properties, bugs, etc. to try and memorize, you will undoubtedly have to turn for help on many occasions. It becomes important for you to know where you can find a solution, and where the solution will be explained in detail enough for you to understand it and be able to avoid it in the future. For example, when I run across a bug that I am not familiar with, the first place I turn to is Position Is Everything. They have wonderful write-ups on various bugs you will find in different browsers. If I just need to lookup a CSS property that I don't use very often, then I turn to "CSS: The Definitive Guide", by Eric Meyer. You need to know the places like this that you can turn to for answers.

Know how to troubleshoot


Knowing how to find the problem is half the battle. There's plenty of ways to go about doing this, so you just have to find the techniques that work for you. While I can say that I haven't ever used diagnostic styling quite to the extent that Eric Meyer posted in his 24ways article, I am a huge fan of using bright colored borders on my block elements to help me locate problem areas. Commenting out blocks of code at a time can also help a lot when trying to find out what elements have the troublesome styles applied to them. And I cannot recommend the Web Developer Toolbar extension for Firefox highly enough. I am so attached to that thing and its many useful troubleshooting features now that it pains me to work on a computer without it.

Show patience and have a sense of humor


Don't worry if it seems like it is taking forever to get to the point where you don't have to look up every little bug. Patience, young Padawan. There are a lot of bugs out there, and it can take awhile before you get to a point where you can recognize one right away.

No matter how much you know, how many books you've read, or how many designs you've developed, there will still come times where a problem comes up that stumps you for awhile. There is just too much information to digest for you to expect to never run into problems. That's when you just need to grin and bear it. Keep plugging away and be willing to laugh at simple mistakes you may make along the way. If CSS wasn't challenging at times, wouldn't that take some of the fun out of it?

Thursday, December 20, 2007

A Microsoft Christmas Miracle

Just in time for the holiday season, Microsoft has let it be known that IE8 (due out sometime in 2008) passes the Acid 2 test in standards mode. This is excellent news for web developers, and quite refreshing to hear coming from the same people who said passing the Acid 2 test simply wasn't a priority for IE7.

For those of you who may be unaware, Acid 2 is a test page for web browser vendors set up by the Web Standards Project (WASP). The intention was for the Acid 2 test to be a tool for browser vendors to use to make sure their browsers could handle some features that we as web developers would love to use. It's a pretty intense little test. If your curious, the WASP walks you through each of the items that Acid 2 tests for.

The timing for Microsoft couldn't have been any better. This announcement comes right after Opera announced they were filing a complaint against Microsoft for their lack of standards compliance.

Now just because a browser actually passes the test doesn't guarantee it will be standards compliant, but this is most definitely a step in the right direction. Add to this the rumor going around that hasLayout will be taken care of now in IE8, and I must say I am getting a little excited here. Of course, with the beta version coming out in the first half of 2008, it will still be quite some time before IE8 takes over the market share currently owned by other versions of the browser. Heck, IE7 still hasn't passed IE6 as the dominant Microsoft browser.

Not to be outdone, BetaNews claims that Firefox 3 Beta also successfully passed the Acid 2 Test. Looks like we may have a pretty intense battle for browser supremacy starting up here in the new year.

Sunday, December 16, 2007

Reinvent the Wheel

A lot of people will tell you not to try and reinvent the wheel. If a script has been written, or a styling effect developed that accomplishes what you want, why spend time trying to create the effect yourself?

I can see their point, and in some situations, I agree. If you are on a tight deadline for a project, you often don't have time to develop that functionality from scratch, and it therefore makes more sense to adapt the structure already developed by someone else.

I do feel, however, that web developers do need to try and create an effect from scratch when they have the opportunity. There are a couple reasons why I feel this is the case.

First off, by forcing yourself to create that layout using CSS, or that form validation script in Javascript from scratch, you force yourself to analyze and learn the intricacies of the language you are dealing with. This knowledge will help to increase your understanding of both the concepts and techniques involved in arriving at a solution for the task. And as far as I know, more knowledge and understanding is never a bad thing.

The other main reason for creating something yourself is because you never know how another point of view may help to create a superior solution to a common problem. Challenge yourself to see if you can improve the solution. I guess you could call this 'modifying the wheel'. If you are going to try and develop a better solution, you should study the ones already out there. Try to see their strengths and weaknesses, and see how you can improve the weaknesses while not losing the strengths.

So over all, I say go ahead and reinvent the wheel. Challenge yourself to create a better solution, and in the process, increase your knowledge. Remember, the first wheels were stone slabs. I tend to think the wheels currently being manufactured for cars, bikes, etc. are probably a little bit better solution.

Wednesday, December 12, 2007

One Clear to Rule Them All

One really common situation for web developers to run into is how to properly clear their floats. There are numerous approaches that have been discussed and used, but only recently have I come across a method that I believe is superior to the rest of the ones I had used up to now. In this post, we will first take a look at the problem caused by floats, and then we will look at some of the ways of fixing that problem.

There are some simple styles that will stay consistent throughout the examples:



  1. #wrap{

  2. border: 1px solid #000;

  3. }

  4. .main{

  5. float: left;

  6. width: 70%;

  7. }

  8. .side{

  9. float: right;

  10. width: 25%;

  11. }



The problem is that when you float an item, you are taking it out of the normal flow of the document, so other elements on the page act as if the floated element is not there. You can see this below (I am using white on black in my examples so they stand out more):

Broken Float

As you can see, #wrap doesn't see .main or .side because they are floated, so our border doesn't extend down. There are numerous proposed solutions to this problem.

Extra Markup


One method that is tried and true, is to add another element inside of #wrap after both of the floats. For example, you could use a div with the class of bottomfix. Now you just set the style of bottomfix to be clear:both, and your wrap will now extend to contain the floats and the bottomfix.

Obviously, if we are shooting for separation of presentation and content (as we should be), this is not an ideal situation. We now have an element in place simply to create a presentational effect.

Instead, let's take a look at some ways of creating the same effect using only CSS. To do so, you have to have a very brief understanding of how Internet Explorer handles floats.

IE Floats


So far it may seem that Internet Explorer (IE) handles floats the same as other browsers, but as we look a little closer, we see that is not the case. Internet Explorer has a proprietary property called hasLayout. For the purpose of this article, just understand that for an element to have "layout", in more cases than not it will need either a width or a height. hasLayout can only be affected indirectly by your CSS styles, there is no hasLayout declaration.

Why is this important to know? Because if an element's hasLayout property is equal to true, that element will auto-contain the float elements. What this means, is that to get IE to clear the floats, we really only have to add width: 100% to #wrap. Now #wrap's hasLayout property is equal to true, and it will now automatically extend to contain the two floated elements.

It's far from being ideal though. While #wrap will now extend properly, we have to be careful about our margins. Elements on the page may respect the containing element (#wrap), but they will not respect the floated elements.

To show this, let's add another div with an id of next. We'll give this div a 1 pixel pink border just so it stands out. Let's also add a 10px bottom margin to the main element. The results in IE are shown below:

IE with layout

As you can see, by adding the width to #wrap, IE will now allow #wrap to contain the floats. You can also see that our 10px margin had no effect. In fact, the top margin of our first paragraph, and bottom margin of our last paragraph are also ignored in IE. So, if you want some space here, you need to use padding, not margins. You can also set a margin to #wrap...since it is the containing element, it's margins are still respected.

Moving On


So now we have cleared the floats in IE, and we understand why. What about the other browsers though? Most will allow you to use the :after pseudo-class to add some content and have that content clear the floats.

  1. #wrap:after{

  2. content: ".";

  3. display: block;

  4. clear: both;

  5. visibility: hidden;

  6. height: 0;

  7. }


What this does in the browsers that recognize it is add a period after the content of #wrap and have it clear the floats. We then use the height and visibility properties to make sure the period doesn't show up. Remember, IE still needs to have "layout" on #wrap because it doesn't recognize the :after pseudo class.

One problem...IE/Mac doesn't auto clear, and doesn't recognize the :after pseudo class. So we have to use some hacks to get IE/Mac and IE/Win to play nicely together. I won't be getting into this, you can find a really nice article about it at Position Is Everything.

An Easier Way


Thankfully, there is an easier way that has been credited to Paul O'Brien. For most browsers to clear the float we simply need to add overflow: hidden to #wrap. Just make sure that there is also a width on #wrap so it has "layout" in IE and you are good to go. Our CSS ends up looking like this:

  1. #wrap{

  2. border: 1px solid #000;

  3. width: 100%;

  4. overflow: hidden;

  5. }

  6. .main{

  7. float: left;

  8. width: 70%;

  9. }

  10. .side{

  11. float: right;

  12. width: 25%;

  13. }


No seriously....that's it. #wrap will now fully contain both the floats. Just keep in mind that if you want to add some space around either of the floated elements, you will want to use padding instead of margins because otherwise IE will ignore it.

Thursday, December 6, 2007

All For One Or One For All

Most of us who are just starting in Javascript and more specifically working with the DOM, can probably write some simple scripts using event handlers. However, there is a more memory efficient method that someone relatively new to Javascript (heck, even some people who have been doing this awhile) might not be aware of - event delegation.

Lucky for us, event delegation is not overly complex, and the jump from using event handlers to using event delegation can be made relatively easily.

Let's start by creating a simple script using event handlers, and then recreate it using event delegation. What we want from our simple script, is that whenever a link is clicked on inside of a specified list, we will get the 'href' of the link alerted for us.

First, we will set up the markup. Nothing fancy to see here, just a list with an id of 'links' which will serve as our hook.

Now we can write a simple script that will go through and add an onclick event handler to each of the links in the list. (Note: for the purpose of simplicity, we will just have our functions below. In a real setting, you would want to do some scoping to protect your variables.)

  1. function prepareAnchors(){

  2. if (!document.getElementById) return false;

  3. var theList = document.getElementById("links");

  4. var anchors = theList.getElementsByTagName("a");

  5. for (var i=0; i < anchors.length; i++){

  6. anchors[i].onclick = function(){

  7. alert(this.getAttribute("href"));

  8. return false;

  9. }

  10. }

  11. }


Again, like I said nothing spectacular. We just grab all the links inside of the ul, loop through them, and assign a function to each individual link's onclick event. (Note: At this point, if you are not able to follow the function above, you are probably not going to get anything useful out of this article. I would instead recommend DOM Scripting by Jeremy Keith.) Now let's recreate the effect using event delegation.

  1. function getTarget(x){

  2. x = x || window.event;

  3. return x.target || x.srcElement;

  4. }

  5. function prepareAnchors(){

  6. if (!document.getElementById) return false;

  7. var theList = document.getElementById("links");

  8. theList.onclick = function(e){

  9. var target = getTarget(e);

  10. if (target.nodeName.toLowerCase() ==='a'){

  11. alert(target.getAttribute("href"));

  12. }

  13. return false;

  14. }

  15. }


This one probably requires a little more explanation. The getTarget() function simply gets the target of the event function, or according to Internet Explorer, the source of the event function.

In prepareAnchors() we get the 'links' list, and assign an onclick event handler to the list as a whole. Now, when anything inside the list is clicked, we simply use getTarget() to find the element that was clicked. If the clicked element was a link, we alert the 'href', if not, we just ignore it.

What are the advantages to using event delegation? Well, for starters, by using one event handler versus many, there is less memory being used to accomplish the same task. On a script this small, you won't be able to tell a performance difference, but larger, more intensive apps will most certainly perform better. Also, by using event delegation, we ensure that our script works even if the DOM has been modified since page load. To see an example of what how modifying the DOM can alter the performance of a script using event handlers, take a look at the excellent comparison done by Chris Heilmann.

Friday, November 30, 2007

CSS, XHTML and Javascript...Oh My!!

Congratulations! You have managed to stumble across my first attempt at having a personal site. While the site is admittedly a bit short on content right now, my goal is for this to eventually turn into a fairly interesting place to visit on a regular basis. Be patient, Rome as they say, was not built in a day.

What can you expect...well, there will be many conversations about what I have learned or come across in the world of web development. In particular, you should eventually see information on things like CSS, XHTML, Javascript, and so on.

There will be some personal updates mixed in I am sure, but I think it is fair to say that the vast majority of posts will be informative and educational in nature.

This is a custom built blog system, so if anything is quirky, or some feature that you feel is seriously important is not here (other than pretty permalinks, they'll be coming soon), please feel free to let me know.

So stay tuned and hopefully I will have something a little more interesting to read for you soon.