Course: JavaScript

Progress (0%)

  1. Foundation

  2. Numbers

  3. Strings

  4. Conditions

  5. Loops

  6. Arrays

  7. Functions

  8. Objects

  9. Exceptions

  10. HTML DOM

  11. CSSOM

  12. Events

  13. Drag and Drop

  14. opt Touch Events

  15. Misc

  16. Project: Analog Clock

Exercise: Redefining firstElementChild

Exercise 44 Easy

Prerequisites for the exercise

  1. HTML DOM — Elements
  2. HTML DOM — Nodes
  3. All previous chapters

Objective

Redefine the firstElementChild property of the Element interface, manually in JavaScript.

Description

In the previous HTML DOM — Elements chapter, we learnt about the firstElementChild property of the Element interface.

It returns the first child node of the calling element that is an element itself, or else the value null if there is no element child node in the calling element or just about no child node at all.

In this exercise, you have to redefine firstElementChild on the Element interface, manually in JavaScript.

You MUST only use properties/methods of the Node interface in your code, NOT any properties/methods of the Element interface, such as children.

View Solution

New file

Inside the directory you created for this course on JavaScript, create a new folder called Exercise-44-Redefining-firstElementChild and put the .html solution files for this exercise within it.

Solution

What we need is simply a while loop that keeps iterating over each subsequent child node of the calling element until an Element instance is found.

Technically, we can use childNodes to accomplish this task, but we're better off at using the firstChild and the nextSibling properties together and thus make the implementation shorter and simpler.

The code below implements the firstElementChild property:

Object.defineProperty(Element.prototype, 'firstElementChild', {
   get: function() {
      var element = this.firstChild;
      while (element && !(element instanceof Element)) {
         element = element.nextSibling;
      }
      return element;
   }
});

Time to try out the implementation.

Consider the following HTML code:

<div id="main">
   <h1>A heading</h1>
   <p>A paragraph</p>
</div>

In the snippet below, we retrieve the nodeName of the first element child of the #main element:

var mainElement = document.getElementById('main').firstElementChild.nodeName
'H1'

Since the nodeName is 'H1', this means that firstElementChild selected the <h1> element, and not the first child text node of <#main>.

But how can we be sure that it's our implementation that's being called? Well, simply by adding a console log statement in there.

In the code below, we add a simple console.log() statement in the definition of firstElementChild:

Object.defineProperty(Element.prototype, 'firstElementChild', {
   get: function() {
console.log('firstElementChild executing'); var element = this.firstChild; while (element && !(element instanceof Element)) { element = element.nextSibling; } return element; } });

Now let's reperform the nodeName check on firstElementChild:

var mainElement = document.getElementById('main').firstElementChild.nodeName
firstElementChild executing
'H1'