Excerpt: Accelerated DOM Scripting with Ajax, APIs and Libraries
Got something to say?
Share your comments on this topic with other web professionals
In: Articles
Published on October 22, 2007
JavaScript libraries have been around in one form or another for almost as long as JavaScript itself. As you go from project to project, it’s inevitable that you’ll find yourself reusing various functions. They become part of your core that you end up copying each time you start up something new. With any good library, code reuse leads to reliability; using the same code on multiple projects means that the code has been exposed to more and more people, enabling bugs or cross-browser issues to be resolved.
You can, of course, use someone else’s library. Using an existing library such as Prototype or jQuery gives you a higher level of reliability that might be difficult to attain through maintaining your own code base.
The trade-off of using a library is file size. Some of these libraries, if taken as a whole, weigh in at more than three hundred kilobytes. However, library developers are tuned in to these kinds of issues and are building their code in a very modular way, enabling you to pick and choose only the features you need. This keeps the amount of code bloat to a minimum. Sites such as Mootools.net even include a module picker that enables you to select whether to compress the files or not.
Libraries serve a number of purposes, which I’ve summarized into three categories:
- Document object model (DOM) access, traversing, and manipulation
- Application conveniences including language extensions
- Widgets
Working with the DOM
Because you’re working with HTML and Cascading Style Sheets (CSS), the DOM is likely the most important interface when it comes to a solid library. It not only improves your efficiency at retrieving elements from the DOM, but it also smoothes the bumps of manipulation and traversal that tend to be inconsistent across browsers.
Many of today’s popular libraries include some methods for working with the DOM, including the capability to select nodes via CSS selectors, and to move through a collection of nodes using functions such as nextSibling()
and previousSibling()
. They often have conveniences for inserting new elements into the DOM, which is a tiresome process at best.
Animation
Part of working with the DOM is handling animation. Being able to handle animation means being able to read and modify several DOM properties, such as the style
object and element offsets. Animation is simply the manipulation of element properties over time. It’s also a great way to add interest to a page and can improve the usability of your site or application if used appropriately.
Application Conveniences
The desktop is slowly moving to the web with applications such as Google Docs and Spreadsheets, and Google Mail. With these types of applications, you are working not only with the DOM but also with large data sets. JavaScript has some basic mechanisms, including arrays and simple iteration, for handling data sets. However, larger data sets often require filtering and ways to quickly load that data into the DOM.
Libraries solve these problems by automating much of the tedium as well as providing a unified application programming interface (API) to various JavaScript and DOM features.
Libraries address the following issues:
- Language extensions and bridges
- Event handling
- AJAX
- Strings and templating
- Working with collections
- Handling JSON and XML
Language Extensions and Bridges
JavaScript and the DOM are great, but they weren’t necessarily designed to do certain things (for example, deep inheritance, in which one object inherits from another, which inherits from another, and so on). Similarly, new language features get implemented in some browsers, but take a while before being introduced into other browsers. These features can be covered with a language bridge, which is a chunk of code that makes the feature of one browser available in another browser. A great example is the Array.push()
method. Older browser versions such as Internet Explorer (IE) version 5 didn’t support it. A simple function such as the following would be used to bridge the gap between the support in IE 5 and other more modern browsers:
// if the method doesn't exist then add it in if (!Array.prototype.push) { Array.prototype.push = function(obj) { this[this.length] = obj; } }
Event Handling
Event handling falls under the category of Language Extensions and Bridges, but I separated it into its own section because it’s so important. Far above any other issue, event handling is the biggest problem that web developers using JavaScript have to deal with. Libraries solve this problem by creating a unified interface for attaching events, maintaining object scope, and stopping events. Let’s take a look at an example from Prototype:
Event.observe(element, 'click', (function(){ alert(this.href) }).bindAsEventListener(element) );
In Prototype, an event object has an observe()
method that enables you to observe events on a particular object. You want to track a click event on an element (a link, in this case). The third parameter enables you to pass in a function to be called when the event is fired. Because this is a simple example, I created an anonymous function, but notice the method bindAsEventListener()
. This method takes a single parameter: the element that should have scope from within the function. When the function gets called, this will refer to that element. The bindAsEventListener()
method makes use of the apply()
method, which ensures that scope is maintained.
AJAX
AJAX originally stood for Asynchronous JavaScript and XML, but it has morphed into an umbrella term that encapsulates a number of technologies. At the core of AJAX, though, is still the idea of using JavaScript to communicate with the server to send and receive data without having to refresh the page. This is done using the XMLHttpRequest
object, often referred to as the XHR object.
The XHR object was originally created by Microsoft as an ActiveX object back in 2000. Mozilla went on to create a native implementation of XHR in 2002; since then, Safari and Opera have added support for it.
AJAX in itself is fairly straightforward, but handling all the contingencies might not be obvious. JavaScript libraries provide a framework for handling successful calls and problem calls (timeouts, for example).
Strings and Templating
When you work with AJAX-based web applications, you frequently take data that has been received from the server and place it on the page somehow. The quickest way to do it is to receive a full HTML snippet from the server and just plunk it on the page. However, that process isn’t very practical. You end up using a lot of bandwidth just to send a little bit of data. Templating solves this problem by enabling data received from the server to be quickly merged with a template and then embedded in the page.
Additionally, web programming constantly uses strings, and having ways to filter, capitalize, or camel-case strings can be extremely handy.
Here’s an example using Prototype to combine a data set with a template to create a list of links:
<ul id="myul"></ul> <script type="text/javascript"> var ul = $('myul'); //the dataset var linkdata = [{name: 'About', url: '/about/'}, {name: 'Contact', url: '/contact/'}, {name: 'Help', url: '/help/'}]; //the template var templ = new Template('<a href="#{url}">#{name}</a>'); //let's add each of these to the document. linkdata.each( function(conv){ li = document.createElement('li'); li.innerHTML = templ.evaluate(conv); ul.appendChild(li); }); </script>
The example starts with an empty unordered list retrieved using the Prototype dollar function $()
. After that, some link information, which is a normal array of object literals, is declared. Next, a new string template, which is another feature of Prototype, is declared. The link data goes through each one using the Prototype each()
method. Prototype automatically makes the each()
method available on all arrays. Each item in the array is evaluated into the template and spit into a new list item, which gets appended to the list. In this case, the link data is embedded in the script. A more common scenario is to pull in the link data via an AJAX call.
Working with Collections
A collection is an array of objects, and the array functionality within JavaScript can be limiting.
Prototype, for example, includes a very robust Enumerable
class for working with collections. You can use methods that will automatically scan the array and remove elements, add elements, or return only a subset of elements.
As you saw in the last example, the each()
method on the array was used to loop through the array. Iteration is much simpler than having to create for loops every time.
Handling JSON and XML
The need to handle data sets is tied mostly to AJAX. These data sets need to be transferred in a format that enables you to quickly understand how the data is structured. The two most popular ways to do this are by using JSON and XML.
JSON, which stands for JavaScript Object Notation, uses a subset of JavaScript to safely define and transport data. JSON parsers are available for dozens of server-side languages, making it extremely easy to integrate into a project. JSON has slowly been taking over XML in popularity for transporting data from the server side to the client side for a couple of reasons:
- JSON is almost always smaller in size because less markup is needed to define the data.
- JSON is quicker to parse and use on the client side because it is native JavaScript.
XML support was built into the responseXML property of the original XHR object being returned. With an XML object, you can use familiar DOM methods to traverse the XML. JavaScript libraries make handling JSON and XML easier by being able to automatically detect which type of data is being returned by an XHR call and parse it appropriately. With JSON, the data can be parsed to prevent against invalid or dangerous information being served up from the server.
Widgets
Widgets are prebuilt components (such as file browsers, tabbed interfaces, or custom dialogs) that can be plugged into an application and solve a discrete task, as can be seen below. Widgets essentially combine the first two categories—DOM manipulation and application conveniences—into a well-oiled machine. Prebuilt widgets are best used for solving common design issues and can take the pain out of having to deal with complicated edge cases that inevitably occur when building complicated interfaces.
How to Choose a Library
With so many libraries out there and so many more to come, how can you ever narrow down the field? Of course, your choice depends entirely on what you need to accomplish. As discussed at the beginning of this chapter, libraries tend to fall into one of the three major categories: DOM tool, application helper, or widget. You need to consider what you might be building and narrow down the field from there.
If you just need to add some interactivity to your blog, such as simple slide effects, you’ll want a library that focuses on the core DOM features along with some basic effects. Mootools or jQuery, for example, might be a good fit.
If you want to build a web application and need to manipulate data sets along with prototyping a complex user interface, using Prototype along with ExtJS might be a better solution.
When looking at any library, be sure to get your hands dirty and take a look at the source. You’ll need to have a good understanding of how the library is put together to be able to take advantage of its power. Plus, it’ll make it easier to do apples-to-apples comparisons.
The Community
Do a search in your favorite search engine to see who’s using the library and the types of things they run into. Having a popular community behind it is a good indication of how solid a library it is. You’ll also find places you can visit, such as blogs and forums, if you ever run into a problem.
The Documentation
With many libraries being built and maintained by only a small team of developers on their own time, you can imagine that documentation falls to the bottom of the to-do list. For example, this was an issue with the Prototype library until only recently. The library had no documentation except for a few third-party resources. A team of individuals banded together to ensure that the library development itself continued on and that a proper site be built in its honor, along with documentation.
Luckily, as more and more people develop on top of these libraries, more examples will make their way onto the Internet, and the documentation will be added to. JavaScript libraries are almost always open-source projects that invite you to contribute to the active development of the library.
Excerpted with permission from Accelerated DOM Scripting with Ajax, APIs and Libraries by Jonathan Snook. Copyright© 2007. Published by Apress.
Related Topics: Technology, Scripting, Programming, DOM
Jonathan Snook is a freelance web developer and consultant. When not working on one project or another, this proud father can be found spending time with his son and wife in beautiful Ottawa, Ontario, Canada.