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 className

Exercise 46 Easy

Prerequisites for the exercise

  1. HTML DOM — Attributes
  2. All previous chapters

Objective

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

Description

The className property, as we learnt about it in the chapter HTML DOM — Attributes, is defined on the Element interface. It is an accessor property meant to mirror the class attribute on the underlying element node.

That is, when the className property is retrieved, the underlying element's class attribute's value is retrieved. Similarly, when a value is set on the className property, it's set on the class attribute of the element node.

In this exercise, you have to redefine className manually in JavaScript.

In your implementation, className must continue to be an accessor property that could be get and set, performing the desired actions as mentioned above.

View Solution

New file

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

Solution

This is a fairly easy exercise to solve.

We just ought to define an accessor property called className, on the Element interface, with a getter and a setter function.

The getter function simply gets the value of the class attribute on the calling element node, whereas the setter function simply sets the value of the attribute on the node.

That's just it.

In the code below, we accomplish this idea:

Object.defineProperty(Element.prototype, 'className', {
   get: function() {
      return this.getAttribute('class');
   },
   set: function(value) {
      this.setAttribute('class', value);
   }
});

Let's now test this implementation.

Recall the following code from the chapter HTML DOM — Attributes while we were learning about the className property:

<h1 id="h1">A heading</h1>
.text-blue {
   color: blue
}
var h1Element = document.getElementById('h1');

// Add the class 'text-blue'.
h1Element.className = 'text-blue';

A heading

It just sets a text-blue class on the <h1> element to get it colored blue.

Now, let's run this same code with our manual className implementation, including some console.log() statements in the implementation to be sure that it really gets put into action:

Object.defineProperty(Element.prototype, 'className', {
get: function() {
console.log('Getter invoked');
return this.getAttribute('class');
},
set: function(value) {
console.log('Setter invoked');
this.setAttribute('class', value);
}
}); var h1Element = document.getElementById('h1'); // Add the class 'text-blue'. h1Element.className = 'text-blue';

A heading

In the link below, open up the console and see whether there is the log Setter invoked present. If there is one, this confirms that it's our implementation that's being invoked in line 15 above.

Live Example

And voila! When we open up the link, there is indeed the desired log present.

The same methodology could be used to check the execution of the getter function associated with className — access it in a get context and then witness the log Getter invoked.