Categories
JavaScript

JavaScript for optimizers #3: Changing element hierarchy

Business case

Our hypothetical case for this chapter is about changing the element hierarchy in the DOM. Our client’s research showed that the visual hierarchy should follow the information hierarchy

We use this insight to create a testing hypothesis:

“Because we saw that our elements don’t follow the information hierarchy, we expect that changing the visual hierarchy will cause an increase in sales. We’ll measure this using conversion-rate.”

We are going to test this hypothesis with the following change: 

Changing the element hierarchy with JavaScript to 1-2-3
The order is now 2-3-1, want it to be 1-2-3

Code

We will execute this change by running the following JavaScript code on the testing page. Try it out for yourself to see how it works!

var block1 = document.querySelector(".block1");
var block3 = document.querySelector(".block3");
function moveUp(element) {
  if (element.previousElementSibling)
    element.parentNode.insertBefore(element, element.previousElementSibling);
}
function moveDown(element) {
  if (element.nextElementSibling)
    element.parentNode.insertBefore(element.nextElementSibling, element);
}
moveDown(block3);
moveUp(block1);

Breakdown

New syntax

The breakdown starts by going over all the new syntax in the example. Future articles will not repeat any of the discussed syntaxes. All the explanations have a link to the complete documentation of the syntax if you need more information.

function functionName(argument) {functionBody} is a function declaration. Functions are subprograms that can be called later on in the script to execute certain tasks. The tasks are determined by the code that is written between the curly brackets. Usually, the function will return a value.

moveUp is an example of a functionName. The name is used when the function is called. A function doesn’t require having a name. A nameless function is called an anonymous function.

The functionBody is the code that runs when the function is called. This can be any JavaScript code that you want. The arguments can be used in the body of the function.

if(condition) conditionBody is a statement that executes the conditionBody when the condition reads true. It is used to create extra logic in your script. When the conditionBody requires multiple lines it needs to be placed between curly brackets.

element.previousElementSibling is an example of a condition because it will return true when an element exists.

Depending on the condition it will skip or run the code
Depending on the condition it will skip or run the code

.previousElementSibling is a property that returns the sibling of an element. It specifically selects the previous element of the one that you selected. Siblings are elements that are on the same level as each other.

previousElementSibling will only select an element that is on the same level
previousElementSibling will only select an element that is on the same level

.parentNode is an object that contains a bunch of methods related to elements that have children. When using this object, you will select the parent element of the element you selected and are able to do something with it. This change depends on the method or property that you use. Without an additional method, you will just select the parent element.

The parent element is one level higher
The parent element is one level higher

.insertBefore(newNode, referenceNode) is a method that inserts an element as a child in the selected element. The first argument(newNode) is the element that gets inserted. The second argument(referenceNode) is the parent element.

It's just the reverse method of the previousElementSibling
It removes the original position of the newNode

.nextElementSibling is a property that is similar to .previousElementSibling. Instead of selecting the previous sibling, it will select the next sibling. It will return null if there are no elements to select.

It's just the reverse method of the previousElementSibling
It’s just the reverse method of the previousElementSibling

functionCall(argument) is the syntax that is used to call a function. You can pass down an argument in a function between the regular brackets for the function to use.

Difference between a function declaration and function call
Difference between a function declaration and function call

Logic

var block1 = document.querySelector(".block1");

In the first line of code, we declare the variable called “block1” and assign an element to it. We select the penguin with the number 1 on its belly using the querySelector method. I gave each of the penguins a corresponding class, so they are easy to select.

var block3 = document.querySelector(".block3");

In the second line of code, we declare the variable called “block3” and assign an element to it. We select the penguin with the number 3 on its belly using the querySelector method.

Both variables get a penguin block assigned
Both variables get a penguin block assigned
function moveUp(element) {
  if (element.previousElementSibling)
    element.parentNode.insertBefore(element, element.previousElementSibling);
}

Our scripts’ first function moves elements up in the DOM within the same level if a sibling in that direction exists. The if statement in this function checks if a previous element exists and then runs the code that switches the elements.

The function is ready to move any selected element one up
The function is ready to move any selected element one up
function moveDown(element) {
  if (element.nextElementSibling)
    element.parentNode.insertBefore(element.nextElementSibling, element);
}

The second function of our script does almost the same as the first function. This function moves elements down in the DOM if an element in that direction exists. It can now be called.

The function is ready to move any selected element one down
The function is ready to move any selected element one down
moveDown(block3);

The first function calls the moveDown function with the block3 variable as the argument. This function will move the penguin with the number 3 on its belly one down.

We started with 2-3-1, now we have 2-1-3
We started with 2-3-1, now we have 2-1-3
moveUp(block1);

The second function calls the moveUp function with the block3 variable as the argument. This function will move the penguin with the number 1 on its belly one up. After this function, we have the element hierarchy that we want.

Now we have the desired result
Now we have the desired result

Exercise

The best way to learn JavaScript is to try it. I want you to change to code, so it reverses the visual hierarchy:

Changing the element hierarchy with JavaScript to 3-2-1
Instead of 1-2-3 we need 3-2-1

Tip: Try using the function calls to get the result.

Want access to the exercise solution?