Moving from jQuery to Dojo: DOM Manipulation

2210
1
05-22-2015 06:21 AM
JamesMilner1
Occasional Contributor
3 1 2,210

As most starters to the ArcGIS JavaScript API, I had to start getting to grips with Dojo. I will make a bit of a concession in saying I've put off learning Dojo but I have been feeling recently that is a necessity to use the JS API to its full potential and avoid bring redundant code. I'll be going back to remove jQuery from some of my examples over the coming months. Apart from it being unnecessary in conjunction to Dojo, jQuery also adds page weight and subsequently wastes of bandwidth and increases page load times. The vast majority of things jQuery does, Dojo can also do. I've been digging into Dojo (there docs are now beautiful!) that I realised it was no way near as 'hard' or 'verbose' as people were making it out to be. In fact when it comes to DOM manipulation and traversal, it's more or less identical to jQuery in most scenarios.

Lets assume we have the following set of very basic HTML in our web page:

<div class="box red">
    <p id="one">1</p>
    <p id="two">2</p>
    <p id="three">3</p>
</div>
<div class="box blue">
    <p class="letter">a</p>
    <p class="letter">b</p>
    <p class="letter">c</p>
</div>

Here's how we might go around selecting elements using jQuery:

     var jQueryOne = $("#red");
     var jQueryRed = $(".red");
     var jQueryRedAndBlue = $(".red .blue");

But realistically this is also trivial using Dojo:

// We're using dojo query
require(["dojo/query", "dojo/domReady"], function(query){

    //query methoods - http://dojotoolkit.org/reference-guide/1.10/dojo/query.html 
    var dojoOne = query("#one");
    var dojoRed = query(".red");
    var dojoRedAndBlue = query(".red .blue");
    var dojoQueryChildren = query(".red >"); // This will return children of .red

});

Notice that there is essentially no difference in the code structure (minus AMD module loading; we load 'query' for DOM selection and domReady to wait until the DOM has loaded). Dojo also returns a NodeList,​ which is essentially a JavaScript Array of the selected DOM elements, decorated with helper functions.

But what if we want to begin to traverse the DOM? In jQuery you may be used to doing something like:

    // https://api.jquery.com/category/manipulation/
    var jQueryChildren = $(".red").children();
    var jQueryParent = $("#one").parent();
    var jQueryParents = $("#one").parents();
    var jQuerySiblings = $("#one").siblings();
    var jQueryNext =  $("#one").next();

And so forth.   Again using Dojo this is actually very similar and simple:

require(["dojo/query", "dojo/NodeList-traverse", "dojo/domReady!"], function(query){
     //NodeList-traverse methods
    var dojoChildren = query(".red").children();
    var dojoParent = query("#one").parent();
    var dojoParents = query("#one").parents();
    var dojoSiblings = query("#one").siblings();
    var dojoNext =  query("#one").next();
    // Full list of traversals here: 
    // http://dojotoolkit.org/reference-guide/1.10/dojo/NodeList-traverse.html 
});

Again notice that the implementations are very similar. This time we loaded in NodeList-traverse as well as query.

Another aspect of dealing with the DOM is wanting to hide, show, style and destroy DOM elements (and such things). In jQuery we may do something like this:

    $("#one").css("color", "orange"); // Change the css color to organge
    $("#two").remove(); // Here for similar methods: https://api.jquery.com/remove/
    $(".blue").removeClass(); // Will remove the blue background color
    $("#one").hide(); // Hides the element
    $("#one").show(); // Shows the element again

You can achieve the same affect using:

    query("#one").style("color", "orange");
    query("#one").remove();
    query(".box").removeClass(".blue");
    query("#one").style("visibility", "hidden");
    query("#one").style("visibility", "visible");

If you ever want to iterate over a returned list of DOM nodes in Dojo you can dojo.forEach ​(allows forEach functionality from ES5 in older browsers also). In jQuery you can use $.each​. Another solution is just to use a native for loop:

for (var i = 0; i < someNodes.length; i++) {
     console.log(someNodes);
}

You can see the full example here on this gist: jQuery to Dojo.html

Hopefully this post as evidenced how simple it is to switch out your jQuery without any real detriment to your code or readability! I'll be doing another couple posts on how to convert your jQuery code; one on AJAX calls another on animations.

Additional Resources:

1 Comment
About the Author
Esri UK developer evangelist. Fan of maps, coffee, 3D, hot sauce, coding, web, Android, drawing, PC gaming.