Book Image

jQuery Design Patterns

By : Greasidis
Book Image

jQuery Design Patterns

By: Greasidis

Overview of this book

jQuery is a feature-rich JavaScript library that makes HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a variety of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript. jQuery solves the problems of DOM manipulation, event detection, AJAX calls, element selection and document queries, element attribute and data management, as well as object management utilities. This book addresses these problems and shows you how to make the best of jQuery through the various design patterns available. The book starts off with a refresher to jQuery and will then take you through the different design patterns such as facade, observer, publisher/subscriber, and so on. We will also go into client-side templating techniques and libraries, as well as some plugin development patterns. Finally, we will look into some best practices that you can use to make the best of jQuery.
Table of Contents (13 chapters)
12
Index

jQuery and DOM scripting

By DOM scripting, we refer to any procedure that alters or manipulates the elements of a web page after it has been loaded by the browser. The DOM API is a JavaScript API that was standardized in 1998 and it provides to web developers a collection of methods that allow the manipulation of the DOM tree elements that the browser creates after loading and parsing the web page's HTML code.

Note

For more information on the Document Object Mode (DOM) and its APIs, you can visit https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction.

By utilizing the DOM API in their JavaScript code, web developers can manipulate the DOM's nodes and add new elements or remove existing elements from the page. The primary use case for DOM scripting was initially limited to client-side form validation, but as the years passed and JavaScript gained the trust of the Enterprise world, more complex user interactions started to be implemented.

The initial version of the jQuery library was first released in August 2006 and it tried to ease the way the web developers were traversing and manipulating the DOM tree. One of its main goals was to provide abstractions that resulted in shorter, easier-to-read, and less error-prone code, while also ensuring cross-browser interoperability.

These core principles that jQuery follows are clearly visible in its homepage, where it presents itself as:

...a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

The abstracted APIs that jQuery provided from the beginning, and the way that different Design Patterns were orchestrated, led to wide acceptance among the web developers. As a result, the jQuery library is referenced by more than 60% of the most visited websites worldwide, according to several sources such as BuiltWith.com (http://trends.builtwith.com/javascript/jQuery).

Manipulating the DOM using jQuery

To have a refresher on jQuery, we will go through an example web page that does some simple DOM manipulations. In this example, we will load a simply structured page that initially looks like the following figure:

Manipulating the DOM using jQuery

We will use some jQuery code to change the page's content and layout and, in order to make its effects clearly visible, we will set it to run about 700 milliseconds after the page has loaded. The result of our manipulations will look like the following figure:

Manipulating the DOM using jQuery

Now let's review the HTML code required for the preceding example:

<!DOCTYPE html> 
<html> 
  <head> 
    <title>DOM Manipulations</title> 
    <link rel="stylesheet" type="text/css" href="dom-manipulations.css">
  </head> 
  <body> 
    <h1 id="pageHeader">DOM Manipulations</h1> 

    <div class="boxContainer"> 
      <div> 
        <p class="box"> 
          Doing DOM Manipulations is easy with JS! 
        </p> 
      </div> 
      <div> 
        <p class="box"> 
          Doing DOM Manipulations is easy with JS! 
        </p> 
      </div> 
      <div> 
        <p class="box"> 
          Doing DOM Manipulations is easy with JS! 
        </p> 
      </div> 
    </div> 

    <p class="box"> 
      Doing DOM Manipulations is easy with JS! 
    </p> 
    <p class="box"> 
      Doing DOM Manipulations is easy with JS! 
    </p>

    <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
    <script type="text/javascript" src="jquery-dom-manipulations.js"></script>
  </body>
</html>

The CSS code used is quite simple, containing only three CSS classes as follows:

.box {
    padding: 7px 10px;
    border: solid 1px #333;
    margin: 5px 3px;
    box-shadow: 0 1px 2px #777;
}

.boxsizer {
    float: left;
    width: 33.33%;
}

.clear { clear: both; }

The preceding code results in a page looking like the first figure when opened in a browser and before our JavaScript code is executed. In the preceding CSS code, we first defined some basic styles for the box, boxsizer, and clear CSS classes. The box class styles the associated elements found in the page by using some padding, a thin border, some margin around, and a small shadow below the elements in order to make them look like a box. The boxsizer class will make the elements that use it to take just 1/3rd of the width of their parent element and create a three-column layout. Finally, the clear class will be used on an element as a break point for the column layout so that all the elements that follow will be positioned below it. The boxsizer and clear classes are not initially used by any element defined in the HTML code, but will be used after the DOM manipulations that we will do in JavaScript.

In the <body> element of our HTML, we initially define an <h1> heading element with ID pageHeader so that it is easily selectable through JavaScript. Right below it, we define five paragraph elements (<p>) with the box class, having the first three of them wrapped inside the three <div> elements and then inside another <div> element with the boxContainer class.

Reaching our two <script> tags, we first include a reference to the jQuery library from jQuery CDN. For more information, you can visit http://code.jquery.com/. In the second <script> tag, we reference the JavaScript file with the required code, for this example, which looks as follows:

setTimeout(function() {
    $('#pageHeader').css('font-size', '3em');

    var $boxes = $('.boxContainer .box');
    $boxes.append(
      '<br /><br /><i>In case we need simple things</i>.');
    $boxes.parent().addClass('boxsizer');

    $('.boxContainer').append('<div class="clear">');
}, 700);

All our code is wrapped inside a setTimeout call to delay its execution, according to the use case described earlier. The first parameter of the setTimeout function call is an anonymous function that will be executed after a timer of 700 milliseconds has expired, as defined in the second argument.

At the first line of our anonymous callback function, we use the jQuery $() function to traverse the DOM and locate the element with the ID pageHeader, and use the css() method to increase its font-size to 3em. Next we provide a more complex CSS selector to the $() function, to locate all the elements with the box class that are descendants of the element with the boxContainer class, and then store the result in a variable named $boxes.

Tip

Variable naming conventions

It is a common practice among developers to use naming conventions for variables that hold objects of a certain type. Using such conventions not only helps you remember what the variable is holding, but also makes your code easier to understand by other developers of your team. Among jQuery developers, it is common to use variable names starting with a "$" sign when the variable stores the result of the $() function (also know as a jQuery collection object).

After we get a hold of the box elements that we are interested in, we append two breaking spaces and some extra text in italics, at the end of each of them. Then, we use the $boxes variable and traverse the DOM tree one level up, using the parent() method. The parent() method returns a different jQuery object holding the parent <div> elements of our initially selected boxes and then we chain a call to the addClass() method to assign them the boxsizer CSS class.

Tip

If you need to traverse all the parent nodes of a selected element, you can use the $.fn.parents() method. If you just need to find the first ancestor element that matches a given CSS selector, consider using the $.fn.closest() method instead.

Finally, since the boxsizer class uses floats to achieve the three-column layout, we need to clear the floats in the boxContainer. Once again, we traverse the DOM using the simple .boxContainer CSS selector and the $() function. Then, we call the .append() method to create a new <div> element with the .clear CSS class and insert it at the end of the boxContainer.

After 700 milliseconds, our jQuery code will have finished, resulting in the three-column layout as shown earlier. In its final state, the HTML code of our boxContainer element will look as follows:

<div class="boxContainer"> 
  <div class="boxsizer"> 
    <p class="box"> 
      Doing DOM Manipulations is easy with JS! 
      <br><br><i>In case we need simple things</i>. 
    </p> 
  </div> 
  <div class="boxsizer"> 
    <p class="box"> 
      Doing DOM Manipulations is easy with JS! 
      <br><br><i>In case we need simple things</i>. 
    </p> 
  </div> 
  <div class="boxsizer"> 
    <p class="box"> 
      Doing DOM Manipulations is easy with JS! 
      <br><br><i>In case we need simple things</i>. 
    </p> 
  </div> 
  <div class="clear"></div> 
</div> 

Method Chaining and Fluent Interfaces

Actually, in the preceding example, we can also go one step further and combine all three box-related code statements into just one, which looks something as follows:

$('.boxContainer .box') 
  .append('<br /><br /><i>In case we need simple things</i>.') 
  .parent() 
  .addClass('boxsizer');

This Syntax Pattern is called Method Chaining and it is highly recommended by jQuery and the JavaScript community in general. Method Chaining is part of the Object Oriented Implementation Pattern of Fluent Interfaces where each method relays its instruction context to the subsequent one.

Most jQuery methods that apply on a jQuery object also return the same or a new jQuery element collection object. This allows us to chain several methods, not only resulting in a more readable and expressive code but also reducing the required variable declarations.