DOM level 3 is a high quality precision tool to work with

The biggest pain in Web development is DOM traversal. You think you’re getting an element node, but you wind up getting an empty text node instead. Or worse still, there’s a bunch of them in your collection and it throws your calculations off. That’s why people use libraries like Prototype, jQuery, Mootools, YUI, Dojo, or any of the others. DOM level 3 finally gives us an unambiguous way to get an element node. ChocolateChip takes advantage of these new traversal tools to make it even easier to get around the DOM. Here’s the breakdown on what we’ve got:

  1. Element.firstElementChild
  2. Element.lastElementChild
  3. Element.previousElementSibling
  4. Element.nextElementSibling
  5. Element.children
  6. Element.childElementCount
  7. Element.first()
  8. Element.last()
  9. Element.previous()
  10. Element.next()
  11. Element.ancestor() New in version 1.1.1
  12. Element.ancestorByTag()
  13. Element.ancestortByClass()
  14. Element.ancestortByPosition()
  15. Element.contains()
  16. Element.isEqualNode()
  17. Element.isSameNode()

As of version 1.3.0, the following methods are available:

  1. Element.is()
  2. Element.not()
  3. Element.isnt() [same as Element.not()]
  4. Element.has()
  5. Element.hasNot()
  6. Element.hasnt() [same as Element.hasNot()]
  7. Element.childElements()
  8. Element.kids()
  9. Element.closest()

Element.firstElementChild

firstElementChild is a new property introduced in DOM level 3. It indicates a first child node that is an element, never an empty text node.

$(function() {
    var article = $("article");
    var firstParagraph = article.firstElementChild;
    firstParagraph.addClass("highlight");     
});

Element.lastElementChild

lastElementChild is a new property introduced in DOM level 3. It indicates a last child node that is an element, never an empty text node.

$(function() {
    var article = $("article");
    var lastParagraph = article.lastElementChild;
    lastParagraph.addClass("highlight");     
});

previousElementSibling is a new property introduced in DOM level 3. It indicates the previous sibling node that is an element, never an empty text node.

Element.previousElementSibling

$(function() {
    var section = $("section:first-of-type");
    // Get the last paragraph:
    var lastPara = section.lastElementChild;
    // Get the paragraph before the last paragraph:
    lastPara.previousElementSibling.addClass("highlight");   	
});

Element.nextElementSibling

nextElementSibling is a new property introduced in DOM level 3. It indicates the next sibling node that is an element, never an empty text node.

    var section = $("section:first-of-type");
    // Get the first paragraph:
    var firstPara = section.firstElementChild;
    // Get the paragraph after the first paragraph:
    firstPara.nextElementSibling.addClass("highlight");   

Element.children

children indicates the children of an element that are actual elements, leaving out any empty text nodes. This is an HTML collection, so it has a length property and can be iterated over with a loop. In contrast, the childNodes property returns all child nodes, including empty text nodes.

var children = $("article").children;
for (var i = 0; children.length < i; i++) {
    children[i].css("background-color: orange; color: red;");
}

Element.childElementCount

DOM level 3 provides a new property for indicating the number of element child nodes minus empty text nodes. Of course, you could also just query the length property of what the children property returns.

var howManyKids = $("article > section:nth-of-type(3)").childElementCount;
$("#childCount").fill("The number of child nodes is: " + howManyKids);

Element.first()

Element.first() is a ChocolateChip convenience method for getting the first child of an element. It’s less letters to type than the methods mentioned earlier, but with the same result.

// Get the last section's first child and fill it with text.
$("section:last-of-type").first().fill("This is the first paragraph.");

Element.last()

Element.last() is a ChocolateChip convenience method for getting the last child of an element. It’s less letters to type than the methods mentioned earlier, but with the same result.

// Get the 8th section's last child and add the class "important"
$("section:nth-of-type(8)").last().addClass("important");

Element.previous()

Element.previous() is a ChocolateChip convenience method for getting the previous sibling of an element. It’s less letters to type than the methods mentioned earlier, but with the same result.

// Get the second paragraph of #MainSection:
var mainParag = $("#MainSection p:nth-of-type(2)");
// Remove the class "secondary".
mainParag.removeClass("secondary");
// Add the class "special" to the paragraph before mainParag:
mainParag.previous().addClass("special");

Element.next()

Element.next() is a ChocolateChip convenience method for getting the next sibling of an element. It’s less letters to type in the methods mentioned earlier, but with the same result.

var firstItem = $("li:first-of-type");
firstItem.addClass("first-item");
firstItem.next().addClass("secondary");

Update: Feb 14, 2011

As of version 1.1.1, ChocolateChip now has a new method for getting the ancestor of a tag: Element.ancestor. The other ancestor methods, Element.ancestorByClass, Element.ancestorByTag and Element.ancestorByPosition, are deprecated and are now aliases to Element.ancestor.

Element.ancestor()

This method accepts one argument which can be one of four types: a position (numeric value), a tag, a class (delimited with an initial “.”) or and id (delimited with an initial “#”). This method can be used to get the ancestor of an element with the matching selector or to verify that an element is the descendant of an element with the supplied selector. In the case of a tag or class, Element.ancestor will return the first instance of the tag or class climbing up from the starting point. Any tag passed as an argument must be plain, meaning, without any attributes. You can test for the presence of an attribute on a tag by using a condition check on the returned node (see examples below).

// Will return the third ancestor tag:
var theAncestor = $("#someID").ancestor(3);
// Will return the element with id of "#main" 
// if it is an ancestor of "#someID":
var theAncestor = $("#someID").ancestor("#main");
// Will return an element with a class of ".myView" if
// it is an ancestor of "#someID":
var theAncestor = $("#someID").ancestor(".myView");
// Will return a subview tag if it is an ancestor of "#someID":
var theAncestor = $("#someID").ancestor("div");
// To find a tag with an attribute, use conditional checking:
var ancestorWithAttribute = $("#someID").ancestor("div");
if (ancestorWithAttribute.hasAttribute("rel") {
    console.log("This tag has a rel value of: " + ancestorWithAttribute.getAttribute("rel");
}

Element.ancestorByTag()

As of version 1.1.1, this tag is deprecated in favor of Element.ancestor() (see above)

Element.ancestortByTag() is a ChocolateChip method for getting the first instance of an ancestor of an element based on that ancestor’s tag.

$(".backButton").ancestorByTag("section").addClass("updated");

Element.ancestorByClass()

As of version 1.1.1, this tag is deprecated in favor of Element.ancestor() (see above)

Element.ancestorByClass() is a ChocolateChip method for getting the first instance of an ancestor of an element based on that ancestor’s class.

$(".nextButton").parentByClass("main").css("border: solid 2px red");

As of version 1.1.1, this tag is deprecated in favor of Element.ancestor() (see above)

Element.ancestorByPostion()

Element.ancestorByPostion() is a ChocolateChip method for getting the ancestor of an element at the designated position in the document. If no position is provided, it returns the immediate parent element. If the position provided is greater than the number of ancestor nodes for that element, it returns the body tag as the final ancestor.

<body>
    <article>
        <section>
            <header>
                <div class="button">
                              //....

$.ready(function() {
    console.log($(".button").ancestorByPosition().nodeName); // => HEADER
    console.log($(".button").ancestorByPosition(1).nodeName); // => HEADER
    console.log($(".button").ancestorByPosition(2).nodeName); // => SECTION
    console.log($(".button").ancestorByPosition(3).nodeName); // => ARTICLE
    console.log($(".button").ancestorByPosition(4).nodeName); // => BODY
    console.log($(".button").ancestorByPosition(20).nodeName); // => BODY
});

New methods since version 1.3.0:

Element.is()

This method returns the element if it matches the argument. The argument can be a tag, class or attribute.

Element.not()

This method returns the element if it does not match the argument. The argument can be a tag, class or attribute.

Element.has()

This method returns the element if one of its child nodes matches the argument. The argument can be a tag, class or attribute.

Element.hasNot()

This method returns the element if one of its child nodes does not match the argument. The argument can be a tag, class or attribute.

Element.childElements()

This method the child nodes of the element. If no argument is provided, it returns all of the element’s child nodes. If an argument is passed, it returns all child nodes that match the argument. Possible arguments are: tag, class or attribute.

Element.kids()

This is an alias for Element.childElements.

Element.closest()

This is an alias for Element.ancestor to match the function of the same name used by jQuery and Zepto.

Advertisements