Modifying the DOM with JavaScript


You will see in your CodePen.io project that there is a panel available for JavaScript. This is equivalent to you creating a file script.js in the same directory as you .html in your local directory.

If you were doing this project locally you would create a script.js file in your computer and link it to the html document by specifying:

<script src="./script.js" defer></script>

in the <head> section of the .html file.

The DOM Elements

The first thing you need to do is to create references to the elements that you want to manipulate in the DOM. In our case, they are the 14 plants currently waiting in the side bars.

dragElement(document.getElementById('plant1'));
dragElement(document.getElementById('plant2'));
dragElement(document.getElementById('plant3'));
dragElement(document.getElementById('plant4'));
dragElement(document.getElementById('plant5'));
dragElement(document.getElementById('plant6'));
dragElement(document.getElementById('plant7'));
dragElement(document.getElementById('plant8'));
dragElement(document.getElementById('plant9'));
dragElement(document.getElementById('plant10'));
dragElement(document.getElementById('plant11'));
dragElement(document.getElementById('plant12'));
dragElement(document.getElementById('plant13'));
dragElement(document.getElementById('plant14'));

What's going on here? You are referencing the document and looking through its DOM to find an element with a particular Id. You can see in the HTML file on the left-most panel that each img is labeled with the class=plant and id=plant1 through id=plant14 respectively. With the above code you are calling .getElementByID(...) from the DOM module called document. We pass that item to the dragElement function that we will build in a minute.

The Closure

Now you are ready to create the dragElement closure, which is an outer function that encloses an inner function or functions (in our case, we will have three).

Closures are useful when one or more functions need to access an outer function's scope. Here's an example:

function displayCandy(){
	let candy = ['jellybeans'];
	function addCandy(candyType) {
		candy.push(candyType)
	}
	addCandy('gumdrops');
}
displayCandy();
console.log(candy)

In this example, the displayCandy function surrounds a function that pushes a new candy type into an array that already exists in the function. If you were to run this code, the candy array would be undefined, as it is a local variable (local to the closure).

How can you make the candy array accessible? Try moving it outside the closure. This way, the array becomes global, rather than remaining only available to the closure's local scope.

Under the element declarations in script.js, create a function:

function dragElement(terrariumElement) {
	//set 4 positions for positioning on the screen
	let pos1 = 0,
		pos2 = 0,
		pos3 = 0,
		pos4 = 0;
	terrariumElement.onpointerdown = pointerDrag;
}

dragElement get its terrariumElement object from the declarations at the top of the script. Then, you set some local positions at 0 for the object passed into the function. These are the local variables that will be manipulated for each element as you add drag and drop functionality within the closure to each element. The terrarium will be populated by these dragged elements, so the application needs to keep track of where they are placed.