Skip to content

Commit

Permalink
Introduced classList, corrections, replaced removeChild() with remove…
Browse files Browse the repository at this point in the history
…(), etc
  • Loading branch information
gmihov001 committed Feb 27, 2024
1 parent 19e11c2 commit 61d9856
Showing 1 changed file with 133 additions and 42 deletions.
175 changes: 133 additions & 42 deletions src/content/lesson/what-is-dom-define-dom.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Thankfully, we have browsers! They let us render our application in a visual int

As you already know, the responsibility of the browser is to transform HTML/CSS code into visual elements. Those elements are mapped into a hierarchy that is stored in RAM memory, and it’s called The DOM.

With JavaScript we can manipulate the DOM (website elements) during runtime (during the application's life cycle).
With JavaScript we can manipulate the DOM (website elements) during runtime (the application's lifecycle).

NOTE: Please always remember that all JavaScript code that you write in your HTML document MUST be wrapped inside a `<script>` tag, like this:

Expand All @@ -33,11 +33,24 @@ NOTE: Please always remember that all JavaScript code that you write in your HTM
</script>
```

Nowadays, we tend to write all of our JS code in a separate file with extension `.js`, in which case the script tag in your html's body needs to look like this:

```html
<body>
<div>some content</div>
<div>more content</div>

<script src="index.js"></script>
</body>
```

This is the preferred way for you to write and link your JS code from now on, as well.

## How to Update Your Website DOM

There are several ways to manipulate the DOM, but the most simple one is `document.write()`. Every time you create a `document.write()` you will be writing onto the HTML whatever string you decide to pass as a parameter to the *write* function.

It does not matter where you write the code. The only thing that matters is that it is wrapped inside a `<script>` tag. For example:
It does not matter where you write the code. The only thing that matters is that it is linked in the HTML with a `<script>` tag. For example:

<iframe width="100%" height="300" src="//jsfiddle.net/BreatheCode/ge5k7ufm/6/embedded/html,result/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>

Expand All @@ -60,11 +73,19 @@ From the moment a website starts being loaded, the browser creates a hierarchy t

## How Do I Access Any Object in the DOM?

Just like we did with CSS, we can select any element in the document. There are 5 methods that allow us to search for whatever we want:
Just like we did with CSS, we can select any element in the document. There are various methods that allow us to target the element that we want. The most current methods are:

### document.querySelector("#some-id")

Returns an instance of **the first element** which matches the CSS selector that you specified.

### document.querySelectorAll(".some-class")

Returns a list (similar to JavaScript array) with **all** elements which match the CSS selector.

### document.querySelector("css-element-selector")
It is preferable that you use these two methods in your work.

Returns an instance of **the first element** found that fits the CSS selector that you specified.
**Other methods which are now considered deprecated but you may see in some code examples:**

### document.getElementById("elementId")

Expand Down Expand Up @@ -97,7 +118,7 @@ let xyz = document.getElementsByName("xyz");
xyz[0].style.color = "red"; // make the first one red
```

## Accessing the Element’s Child
## Accessing the Element’s Children

It is very common to need to change an element’s child. For example:

Expand All @@ -106,45 +127,41 @@ It is very common to need to change an element’s child. For example:
+ Hiding all the children with a specific class.
+ And the list goes on!

The best way to retrieve the child elements of any DOM element is by using its childNodes properties, like this:
The best way to retrieve the children elements of any DOM element is by using its `.children` property, like this:

### element.children

This returns an array with all the element’s children nodes.

Given the following example, open the code in JSFiddle and console.log `tableElm.children` at the end of the existing JavaScript code:
<iframe width="100%" height="300" src="//jsfiddle.net/BreatheCode/a3grunqj/2/embedded/js,html,result/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>

<div align="right"><small><a href="//jsfiddle.net/BreatheCode/a3grunqj/2/embedded/js,html,result/">Click here to open demo in a new window</a></small></div>

Open the Console in the Chrome Inspector feature. What did you observe?

You should have gotten an array (*HTMLCollection*) with two items - the `thead` and `tbody` which are the table's direct children. Because you see that `tableElm.children` gives you an array-like structure in JavaScript, you could guess that to get the first element (*thead*), you can simply code `tableElm.children[0]`.

Now go to the end of the JS code and add another console.log - `tableElm.children[1].children`.

### element.childNodes
Can you guess what this will return in the console? Try it out!

This returns an array with all the element’s children nodes.
Here is an explanation of the other properties used in the example:

```javascript
let x = document.getElementById("myDIV");
x.querySelector(".random").style.background = "green";
// get the first #myDIV child with the .random class

let x = document.getElementById("myDIV");
x.querySelector("h3,h2").style.background = "blue";
// get the first #myDIV child with the tag <h3> or <h2>

let tableElm = document.getElementById("people");
let tableElm = document.querySelector("#people");
let trArray = tableElm.querySelectorAll("tr");
trArray[3].style.background = "red";
// get an array with all of #people's children with tag <tr>
// get an array with all elements nested within the #people table, of type <tr> - not necessarily direct children
```

<iframe width="100%" height="300" src="//jsfiddle.net/BreatheCode/a3grunqj/2/embedded/js,html,result/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>

<div align="right"><small><a href="//jsfiddle.net/BreatheCode/a3grunqj/2/embedded/js,html,result/">Click here to open demo in a new window</a></small></div>

## The innerHTML

As you already know, each element in the HTML document can have some sort of HTML content. It does not matter if it is a `<p>`, `<div>`, `<a>` or any other HTML element; it can have its own innerHTML combined with more HTML content.

![what is dom](https://github.com/breatheco-de/content/blob/master/src/assets/images/2387325b-338c-4c18-bb0f-2f95ed28901f.png?raw=true)

The `.innerHTML` property gives you the ability to retrieve or set the content of whatever element you have in your JavaScript. For example:

```javascript
document.getElementsByTagName("div")[0].innerHTML = "abc";
// innerHTML can be used to insert plain text content or HTML, this creates a list inside a <div> element
```

> ☝️ You can find another 2 properties on the internet: `nodeValue` and `textContent`, but they are not really universally used and are more limited in functionality.

## Adding Elements to the Document

Expand All @@ -155,7 +172,7 @@ Let's say that you have selected a `<div>` with the `id="myFirstDiv"` and you wa
**You can use the appendChild function like this:**

```javascript
let divElem = document.getElementById("myFirstDiv");
let divElem = document.querySelector("myFirstDiv");
let myNewHOne = document.createElement("h1");
let t = document.createTextNode("Hello World");
myNewHOne.appendChild(t); // This adds the text content to the <h1>
Expand All @@ -167,48 +184,122 @@ Now, let's say that we have a `<ul>` with 2 elements, but we want to insert a ne
**We can use the function `insertBefore` for that case – like this:**

```javascript
...
let newItem = document.createElement("li");
let textNode = document.createTextNode("Water");
newItem.appendChild(textNode);
let list = document.getElementById("myList");
list.insertBefore(newItem, list.childNodes[0]); // adding the newItem before the FIRST child of the list
```


## innerHTML

As you already know, each element in the HTML document can have some sort of HTML content. It does not matter if it is a `<p>`, `<div>`, `<a>` or any other HTML element; it can have its own innerHTML combined with more HTML content.

![what is dom](https://github.com/breatheco-de/content/blob/master/src/assets/images/2387325b-338c-4c18-bb0f-2f95ed28901f.png?raw=true)

The `.innerHTML` property gives you the ability to retrieve or set the content of whatever element you have in your JavaScript. For example:

```javascript
document.getElementsByTagName("div")[0].innerHTML = "abc";
// innerHTML can be used to insert plain text content or HTML, this creates a list inside a <div> element
```

It can also be used to add entire new elements into your HTML without being so verbose as the `createElement` examples above. Let's rework the `"Hello World" to see the difference:

```javascript
document.querySelector("myFirstDiv").innerHTML += `<h1>Hello World</h1>`
```

Dramatic difference!!! We achieved the same result with one line of code that previously required 5 lines.

By using template literals (**``**) we can even break down the HTML elements onto separate rows, so it is easier to read them, and also we can use variable values, instead of hard-coded ones:

```javascript
let greeting = "Hello World"
document.querySelector("myFirstDiv").innerHTML += `
<div>
<h1>
${greeting}
</h1>
</div>
`
```

> ☝️ Get into the habit of using this approach as it is much more concise and straightforward which also makes your code easier to read.
> You can find another 2 properties on the internet: `nodeValue` and `textContent`, but they are not really universally used and are more limited in functionality.

## Removing Elements from the Document

The `removeChild()` function is great for removing an element from the DOM and, consequentially, from the HTML document as well. You will have to specify who is the parent of the element that you are trying to delete.
The most straightforward method to remove an element from the DOM is the `remove()` method.

For example, if we want to remove all the elements from a <ul> list:
For example, if we want to remove a `<p>` element with `id="firstP"`, we can do the following:

```javascript
// Removing all children from an element
let element = document.getElementById("myFirstUL");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
let element = document.querySelector("p#firstP");
element.remove();
```

## Changing the Attributes
## Changing Attributes

To change any attribute of any object in the DOM, we need to use the `.attribute` property just like this:

```javascript
// Changing attributes
let element = document.getElementById("myElementId");
element.attribute = "whatever";
let element = document.querySelector("#someId");
element.someAttribute = "newValue";
```

For example, to change the value of a button element, you would need to code this:

```javascript
// Changing value attribute
let btn = document.querySelector("#myButton");
btn.value = "newButton";
```

## Changing the Styles

You can also change any CSS rule or property applied to the HTML elements by using the `.style` attribute, like this:

```javascript
// Changing styles
let element = document.getElementById("myElementId");
let element = document.querySelector("#myElementId");
element.style.color = "red";
element.style.background = "blue";
element.style.backgroundColor = "blue";
```

> ☝️ Notice how css properties which consist of two words, like `background-color`, become one word in camel case in the DOM - `backgroundColor`.
## Changing Classes

Many times as you dynamically change the content of your application, you would want to change the classes of some elements, because classes allow us to give our elements different styling and functionality.

Imagine that you are given a bootstrap button:

```html
<button id="myButton" class="btn btn-warning">Submit</button>
```

You would like to change its background color from yellow to red at some point of your application's runtime. You can do that by simply exchanging its bootstrap classes for background color:

```javascript
// Changing classes
let btn = document.querySelector("#myButton");
btn.classList.remove("btn-warning");
btn.classList.add("btn-danger");
```

You can do the same thing with your own custom classes.

As you can see, the `classList` property gives you access to the classes of a given element, and you can add or remove classes.

With this knowledge, now research and make sure to understand the method [`classList.toggle("newClass")`](https://www.w3schools.com/howto/howto_js_toggle_class.asp).

## Further reading

For more information about accessing the DOM, see: https://developer.mozilla.org/en-US/docs/Web/API/Document
Expand Down

0 comments on commit 61d9856

Please sign in to comment.