From DHTML to DOM Scripting, Part 2

By Christian Heilmann


Desktop-as-a-Service Designed for Any Cloud ? Nutanix Frame

The function linksInit() checks whether DOM is available (as it is the only function calling the others, we don't need to check for it inside them again) and creates a link with a target of # and open as the link text. It then invokes the appendLink() function and sends the newly generated link as a param-eter. Notice it doesn't send a target element, which means elementId is null and appendLink() adds the link to the main body of the document.

The second time initLinks() invokes createLink(), it sends the target closed.html and close as the link text and applies the link to the HTML element with the ID main via the appendLink() function. If there is an element with the ID main, appendLink() adds the link to this one; if not, it uses the document body as a fallback option.

If this is confusing now, don't worry, you will see more examples later on. For now, it is just important to remember what functions are and what they should do:

  • Functions are there to do one task over and over again--keep each task inside its own function; don't create monster functions that do several things at once.
  • Functions can have as many parameters as you wish, and each parameter can be of any type--string, object, number, variable, or array.
  • You cannot predefine parameters in the function definition itself, but you can check whether they were defined or not and set defaults with an if condition. You can do this very succinctly via the ternary operator, which you will get to know in the next section of this chapter.
  • Functions should have a logical name describing what they do; try to keep the name close to the task topic, as a generic init(), for example, could be in any of the other included JavaScript files and overwrite their functions.
Object literals can provide one way to avoid this problem, as you'll see later in this chapter.

Short Code via Ternary Operator

Looking at the appendLink() function shown earlier, you might get a hunch that a lot of if conditions or switch statements can result in very long and complex code. A trick to avoid some of the bloating involves using something called the ternary operator. The ternary operator has the following syntax:
var variable = condition ? trueValue:falseValue;
This is very handy for Boolean conditions or very short values. For example, you can replace this long if condition with one line of code:
// Normal syntax
var direction;
// Ternary operator
var direction = x < 200 ? 1 : -1;
Other examples:
t.className = t.className == 'hide' ? '' : 'hide';
var el = document.getElementById('nav')
       ? document.getElementById('nav')
       : document.body;
You can also nest the ternary selector, but that gets rather unreadable:
y = x <20 ? (x > 10 ? 1 : 2) : 3;
// equals

Sorting and Reuse of Functions

If you have a large number of JavaScript functions, it might be a good idea to keep them in separate .js files and apply them only where they are needed. Name the .js files according to what the functions included in them do, for example, formvalidation.js or dynamicmenu.js. This has been done to a certain extent for you, as there are a lot of prepackaged JavaScript libraries (collections of functions and methods) that help create special functionality. We will look at some of them in Chapter 11 and create our own during the next few chapters.

Variable and Function Scope

Variables defined inside a function with a new var are only valid inside this function, not outside it. This might seem a drawback, but it actually means that your scripts will not interfere with others--which could be fatal when you use JavaScript libraries or your own collections. Variables defined outside functions are called global variables and are dangerous. We should try to keep all our variables contained inside functions. This ensures that our script will play nicely with other scripts that may be applied to the page. Many scripts use generic variable names like navigation or currentSection. If these are defined as global variables, the scripts will override each other's settings. Try running the following function to see what omitting a var keyword can cause:
<script type="text/javascript">
  var demoVar=1 // Global variable
  alert('Before withVar demoVar is' +demoVar);
  function withVar()
    var demoVar=3;
  alert('After withVar demoVar is' +demoVar);
  function withoutVar()
  alert('After withoutVar demoVar is' +demoVar);
While withVar keeps the variable untouched, withoutVar changes it:
Before withVar demoVar is 1
After withVar demoVar is 1
After withoutVar demoVar is 3

Keeping Scripts Safe with the Object Literal

Earlier we talked about keeping variables safe by defining them locally via the var keyword. The reason was to avoid other functions relying on variables with the same name and the two functions overwriting each other's values. The same applies to functions. As you can include several JavaScripts to the same HTML document in separate script elements your functionality might break as another included document has a function with the same name. You can avoid this issue with a naming convention, like myscript_init() and myscript_validate() for your functions. However, this is a bit cumbersome, and JavaScript offers a better way to deal with this in the form of objects.

You can define a new object and use your functions as methods of this object--this is how JavaScript objects like Date and Math work. For example:

<script type="text/javascript">
  myscript=new Object();
    // Some code
   // Some code
Notice that if you try to call the functions init() and validate(), you get an error, as they don't exist any longer. Instead, you need to use myscript.init() and myscript.validate(). Wrapping all your functions in an object as methods is analogous to the programming classes used by some other languages such as C++ or Java. In such languages, you keep functions that apply to the same task inside the same class, thus making it easier to create large pieces of code without getting confused by hundreds of functions.

The syntax we used is still a bit cumbersome, as you have to repeat the object name over and over again. There is a shortcut notation called the object literal that makes it a lot easier. The object literal has been around for a long time but has been pretty underused. It is becoming more and more fashionable nowadays, and you can pretty much presume that a script you find on the web using it is pretty good, modern JavaScript. What the object literal does is use a shortcut notation to create the object and apply each of the functions as object methods instead of standalone functions. Let's see our three functions of the dynamic links example as a big object using the object literal:
var dynamicLinks={
    if (!document.getElementById || !document.createTextNode)
       { return; }
    var openLink=dynamicLinks.createLink('#','open');
    var closeLink=dynamicLinks.createLink('closed.html','close');
    if (linkTarget == null) { linkTarget = '#'; }
    if (linkName == null) { linkName = 'dummy'; }
    var tempLink=document.createElement('a');
    return tempLink;
    var element=false;
    if (elementId==null || !document.getElementById(elementId))
As you can see, all the functions are contained as methods inside the dynamicLinks object, which means that if we want to call them, we need to add the name of the object before the function name. The syntax is a bit different; instead of placing the function keyword before the name of the function, we add it behind the name preceded by a colon. Additionally, each closing curly brace except for the very last one needs to be followed by a comma. If you want to use variables that should be accessible by all methods inside the object, you can do that with syntax that is quite similar:
var myObject=
This might be a lot right now, but don't worry. This chapter is meant as a reference for you to come back to and remind you of a lot of good practices in one place. We will continue in the next chapter with more tangible examples, and rip open an HTML document to play with the different parts.


You have done it; you finished this chapter, and you should now be able to separate modern and old scripts when you see them on the Web. Older scripts are likely to
  • Use a lot of document.write().
  • Check for browsers and versions instead of objects.
  • Write out a lot of HTML instead of accessing what is already in the document.
  • Use proprietary DOM objects like document.all for MSIE and document.layers for Netscape Navigator.
  • Appear anywhere inside the document (rather in the <head> or included via <script src="---.js">) and rely on javascript: links instead of assigning events.
You've learned about putting JavaScript into stand-alone .js documents instead of embedding it into HTML and thereby separating behavior from structure. You then heard about using object detection instead of relying on browser names and what progressive enhancement means and how it applies to web development. Testing user agent capabilities instead of names and versions will ensure that your scripts also work for user agents you might not have at hand to test yourself. It also means that you don't have to worry every time there is a new version of a browser out--if it supports the standards, you'll be fine.

We talked about accessibility and what it means for JavaScript, and you got a peek at a lot of coding practices. The general things to remember are

  • Test for the objects you want to use in your scripts.
  • Make improvements in an existing site that already works well without client-side scripting instead of adding scripts first and adding nonscripting fallbacks later on.
  • Keep your code self-contained and don't use any global variables that might interfere with other scripts.
  • Code with the idea in mind that you will have to hand this code over to someone else to maintain. This person might be you in three months' time, and you should be able to immediately understand what is going on.
  • Comment your code's functionality and use readable formatting to make it easy to find bugs or change the functions.
This is the lot--except for something called an event handler, which I've talked about but not actually defined. I'll do so in Chapter 5. But for now, sit back, get a cup of coffee or tea, and relax for a bit, until you're ready to proceed with learning how JavaScript interacts with HTML and CSS.

This chapter is excerpted from Beginning JavaScript with DOM Scripting and Ajax from Apress Publishing.

Page 2 of 2

Previous Page
1 2

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
Thanks for your registration, follow us on our social networks to keep up-to-date