Skip to main content

Dojo & jQuery side by side. Part 1: DOM Basics

Posted by Christopher Imrie in Code
Dojo and jQuery side by side. Part 1: DOM Basics
Dojo is a fantastic toolkit that we have used on many projects here at moresoda.  Although we still love and use jQuery nearly everyday, we use Dojo on projects where the front end requirements are more complicated than your average DOM manipulation and HTML5 shims.
This article isnt about preaching Dojos benefits though.  If you have a read of the features and benefits of Dojo you can make up your own mind.  That being said, Dojo can be harder to get into since is it a much larger than jQuery.
Hence my aim here is to provide a simple, unbiased side by side comparison of common jQuery operations and how they are achieved in Dojo.
Lets go!

Loading the script from the Google CDN

Both can be loaded from the Google CDN.  If you use any components of Dojo that are not part of Dojo Base (the file being loaded by the script tag below), they will be dynamically pulled from the CDN as well.
//jQuery
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>

//Dojo
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7/dojo/dojo.js" type="text/javascript"></script>

Waiting for the DOM Ready Event

The Dojo ready and jQuery ready methods are identical.  With Dojo you dont need to specify the document, as the current document is implied.
//jQuery
 $(document).ready( function(){
   // Your code here
 });

 //Dojo
dojo.ready( function () {
    // Your code here
})

Querying the DOM

Both Dojo and jQuery support the CSS3 selectors.  Hence there is no real difference in usage here apart from dojo being more verbose.
When querying the DOM, each method returns their own array type collection of nodes that have been matched.  jQuery returns a jQuery Collection and Dojo returns a Dojo NodeList.  Both can be accessed just like an array but they allow chaining of methods to quickly add/remove classes, change properties etc.
//jQuery
$("some CSS3 selector");               // Returns a jQuery Collection (kind of like an array)

//Dojo
dojo.query("some CSS3 selector");      // Returns a Dojo Node List (kind of like an array)

Adding and removing classes

Both methods are identical and can be chained infinitely to add and remove classes in a single call.

Adding

//jQuery
$("p:last-of-type").addClass("last");

//Dojo
dojo.query("p:last-of-type").addClass("last");

Removing

//jQuery
$("p:last-of-type").removeClass("last");

//Dojo
dojo.query("p:last-of-type").removeClass("last");

Getting and Manipulating HTML Attributes

Once again the setter and getter methods are identical, making it very easy to remember!  As with class manipulation, both will allow these to be chained together for convenience.

Getting attributes

//jQuery
$("a.external_link").attr("target");

//Dojo
dojo.query("a.external_link").attr("target");

Setting attributes

//jQuery
$("a.external_link").attr("target", "_blank");

//Dojo
dojo.query("a.external_link").attr("target", "_blank");

Looping over multiple queried DOM nodes

Since the object returned from querying the DOM is array like in nature, you can loop through the items.  Both jQuery Collections and Dojo NodeLists contain built in methods that allow you to conveniently lopp through the items.
Take note that the technique for accessing the current item in the loop is different:
//jQuery
$(".someClass").each( function() {
    $(this).addClass("active");                         //Current node in the loop is available as "this"
});

//Dojo
dojo.query(".someClass").forEach( function(node) {
    dojo.addClass(node, "active");                      //Current node in the loop is available as function argument "node"
});

Creating HTML Nodes

jQuery introduced a novel way of creating HTML elements which was by parsing a string of HTML text string into its correct HTML Object.  Due to its convenience, Dojo has a method that allows you to achieve the same thing.
//jQuery - HTML Parsing
var newNode = $("<h1>This is a new heading</h1>");

//jQuery - Alternate
var newNode = $("<h1/>").prop({
    "innerHTML" : "This is a new heading"
});

//Dojo - HTML parsing
var newNode = dojo.toDom("<h1>This is a new heading</h1>");            

//Dojo - Alternate
var newNode = dojo.create("h1", {
    "innerHTML" : "This is a new heading"                             
})

Inserting HTML nodes into the DOM

As opposed to using multiple methods to dictate the position to insert a new element, Dojo opts for a single method with a string argument that dictates the position the new node should be inserted (eg: first, last, after etc).

Append

//jQuery
$("#header").append(newNode);

//Dojo
dojo.place( newNode, "header", "last")

Prepend

//jQuery
$("#header").prepend(newNode);

//Dojo
dojo.place( newNode, "header", "first");

Before

//jQuery
$("#header").before(newNode);

//Dojo
dojo.place( newNode, "header", "before");

After

//jQuery
$("#header").after(newNode);

//Dojo
dojo.place( newNode, "header", "after");

Creating and Inserting HTML nodes in a single go

Both provide convenience methods for creating and inserting in a single call.  Dojo’s create method’s third parameter expects the name of an element ID (in the example below, “#article”) but it will also accept an HTML node found by using the dojo.query method.
//jQuery
$("<p>Howdy Ho!</p>").prependTo("#article");

//Dojo
dojo.create("p", {
    "innerHTML": "Howdy Ho!"
}, "article", "first");                                 // Third parameter to this function accepts a CSS ID or an HTML Node.

Removing HTML Nodes from the page

Neither will actively destroy the object, but merely detach it from the DOM.  If the node removed is not referenced anywhere else in the currently running script, then the browser’s garbage collection will destroy the object for you.  Dojo does have an additional dojo.destroy method which will destroy an object for you.
//jQuery
$("#header li").remove();                               //Removes all items in the collection from the page

//Dojo
dojo.query("#header li").orphan();                      //Loops over each item found and hands it over to the destroy node method

Traversing

Dojo does not load the traversing methods by default.  Hence if you want to use the methods below you will need to load the NodeList-traverse extensions before using them.

Next element

//jQuery
$("li:first-of-type").next();                       //Next nodes after found nodes, if available
$("li:first-of-type").next(".active");              //Next nodes, but only if they match the CSS selector


//Dojo
dojo.require("dojo.NodeList-traverse");             //This loads the traversion extensions to Dojo NodeLists.  Only needs to be called once

dojo.query("li:first-of-type").next();
dojo.query("li:first-of-type").next(".active");

Previous element

//jQuery
$("li:first-of-type").prev();                       //Previous nodes after found nodes, if available
$("li:first-of-type").prev(".active");              //Previous nodes, but only if they match the CSS selector


//Dojo
dojo.require("dojo.NodeList-traverse");            

dojo.query("li:last-of-type").prev();
dojo.query("li:last-of-type").prev(".active");

Child elements

//jQuery
$("ul.nav").children();                             // All child nodes of the found nodes
$("ul.nav").children(".active");                    // All child nodes, but only if they match the CSS selector 


//Dojo
dojo.require("dojo.NodeList-traverse");             

dojo.query("ul.nav").children();
dojo.query("ul.nav").children(".active");

Parent element

// jQuery
$("li.active").parent();  

// Dojo
dojo.require("dojo.NodeList-traverse");            
dojo.query("ul.nav").parent();

Comments

Popular posts from this blog

Quicksort implementation by using Java

 source: http://www.algolist.net/Algorithms/Sorting/Quicksort. The divide-and-conquer strategy is used in quicksort. Below the recursion step is described: 1st: Choose a pivot value. We take the value of the middle element as pivot value, but it can be any value(e.g. some people would like to pick the first element and do the exchange in the end) 2nd: Partition. Rearrange elements in such a way, that all elements which are lesser than the pivot go to the left part of the array and all elements greater than the pivot, go to the right part of the array. Values equal to the pivot can stay in any part of the array. Apply quicksort algorithm recursively to the left and the right parts - the previous pivot element excluded! Partition algorithm in detail: There are two indices i and j and at the very beginning of the partition algorithm i points to the first element in the array and j points to the last one. Then algorithm moves i forward, until an element with value greater or equal

Live - solving the jasper report out of memory and high cpu usage problems

I still can not find the solution. So I summary all the things and tell my boss about it. If any one knows the solution, please let me know. Symptom: 1.        The JVM became Out of memory when creating big consumption report 2.        Those JRTemplateElement-instances is still there occupied even if I logged out the system Reason:         1. There is a large number of JRTemplateElement-instances cached in the memory 2.     The clearobjects() method in ReportThread class has not been triggered when logging out Action I tried:      About the Virtualizer: 1.     Replacing the JRSwapFileVirtualizer with JRFileVirtualizer 2.     Not use any FileVirtualizer for cache the report in the hard disk Result: The japserreport still creating the a large number of JRTemplateElement-instances in the memory        About the work around below,      I tried: item 3(in below work around list) – result: it helps to reduce  the size of the JRTemplateElement Object        

Stretch a row if data overflows in jasper reports

It is very common that some columns of the report need to stretch to show all the content in that column. But  if you just specify the property " stretch with overflow' to that column(we called text field in jasper report world) , it will just stretch that column and won't change other columns, so the row could be ridiculous. Haven't find the solution from internet yet. So I just review the properties in iReport one by one and find two useful properties(the bold  highlighted in example below) which resolve the problems.   example: <band height="20" splitType="Stretch" > <textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="true"> <reportElement stretchType="RelativeToTallestObject" mode="Opaque" x="192" y="0" width="183" height="20"/> <box leftPadding="2"> <pen lineWidth="0.25"/>