Skip to content

Nodes and collections

jasononeil edited this page Oct 27, 2012 · 3 revisions

Nodes

When working with Xml (or Html, the DOM, whatever you want to call it) - you are essentially dealing with a tree of 'nodes'. It will often look like this:

<html>                 <- that is an element node
  <head>               <- another element node
    <title>            <- another element
      My Page          <- a text node
    </title>
  </head> 
  <!-- comment -->     <- a comment node
</html>

Each one of those is a node... there are element nodes, text nodes, comment nodes, document nodes and other types too. When working with the Xml, we're inevitably trying to work with Nodes. We might want to set an attribute, add a child, move it around or change the text contents - all of these operations happen on a specific node.

In Javascript, these are called Nodes. In Haxe, when you target Javascript, these are recognised by the HtmlDom typedef.

On other Haxe targets, we have the cross platform Xml Class. While not the most full featured API, it is cross platform on all Haxe targets - so that's a great foundation. Each Xml object in Haxe represents a node in your Xml.

In short, on Javascript, a Node is a Javascript DOM Node, on other platforms, a Node is an Xml object. While the implementations underneath are different, Detox tries to smooth over the differences so that you don't have to worry.

When using the Detox library, you can use the type "DOMNode" and it will automatically refer to the correct type for whichever platform you're targeting.

Collections

Sometimes, working with individual nodes could get tiring. For example:

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

What if you wanted to change something with all three <li> nodes at once? You could do them individually, or wrap all of your operations in a for() loop. Neither of these are optimal though.

Hence, we introduce "collections". Collections are basically a group of nodes, and you can work with them as one. If you add an attribute, it will be added to all the nodes in the collection. If you set the text content, it will set it for all the nodes in the collection.

Examples of collections:

  • All the children of an element
  • All of the <a> Nodes (links) in an entire document
  • A bunch of Nodes from some Xml that you just parsed.
  • All of the descendant Nodes of the entire element.
  • Random Nodes that you manually add to a collection that have nothing else in common.
  • A single Node (say you ask for all children, and there is only one child)
  • Empty (say you ask for all children, but there are none)

In Detox, we use the DOMCollection class for all of our collections. While you could start a DOMCollection and add Nodes manually, like so:

var c = new DOMCollection();
c.add(someNode);
c.addCollection([node1, node2]);

... but most of the time, that's not how we do it. You're more likely to get a collection from:

  • Parsing some HTML

    "<b>Bold</b><i>Italic</i>".parse(); - returns a collection with both <b> and <i> inside it.

  • Searching the DOM

    "li".find(); - returns a collection of every <li> element in the document

  • Finding the children, siblings, ancestors or descendants of a node

    myNode.ancestors(); - returns a collection containing myNode's parent, and the parent's parent, etc.
    myNode.children(); - returns a collection containing the direct children of myNode.
    myNode.descendants(); - returns a collection of myNode's children, and their children, etc.
    myCollection.next(); - returns a collection containing the next sibling of all of the nodes in the current collection.

When working with collections, it doesn't matter how many Nodes are in them. If there are hundreds of nodes - all of them will be affected. If there are zero nodes - nothing will happen, but no errors will be thrown either. The code will just continue on it's merry way. If you want to check if a collection is empty, you can check that collection.length > 0

Comparisons to jQuery

Since most people are familiar with jQuery or something similar, a quick comparison:

  • jQuery always works with a collection. In order to use jquery on a node myBtn, you wrap it with $(myBtn) and then you can work with that. We give you the option to either wrap the normal node, or to ignore it.
  • Because you sometimes work with a collection and sometimes not, you'll occasionally try to do something like for (n in myNode) instead of for (n in myCollection), which won't work. But the Haxe compiler will let you know and give a compile time error.
  • It's possible there's a performance difference for not having to wrap all of your objects before using them in Detox, but I haven't looked into.
Clone this wiki locally