# JS in HTML & DOM

# Linking JS to HTML

# Motivation

During this course, we'll mostly focus on front-end development with React

However, it helps to understand some of the basics on how to interact with web pages using pure JavaScript

We won't dive deep into making complex websites with pure JavaScript without a framework, but we'll glance at some of the basics

* Javascript in an HTML file is written within the <script> tags.
* As a rule of thumb, aim for inserting <script> in the bottom of the <body>
  * The page loads faster as the browser compiles the script only  _after _ loading the page
* However, if you  _need _ the script to load before the page, add it to <head>.

<html>

<head>

</head>

<body>

<p>Hello there!</p>

<script>

__Insert__  __ __  __JS__  __ __  __here__

</script>

</body>

</html>

Exercise 1: HTML + JS hello world

Add some functionality to your HTML page.

Create a function that prints "hello world" . Call this function in your script!

# Events

* Creating a function and then running it when loading the page doesn't really add  _interactivity _ to a website
  * Luckily, JavaScript functions can be bound to various  __events__
* The fastest way: define the function inside the <script> tags and then give some element onclick event, e.g.,
    * <div onclick="someFunction()"> </div>
  * (Another example of an event would be onmouseover)
* This method is a bit tacky, as it mixes HTML with JS
  * generally we want those to be  __separated__ !

__addEventListener __ (The better way)

Better way to implement the onclick and other methods is by adding the event listener fully in code

First, find the element with

[document.getElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)

__querySelector (example later)_

__querySelectorAll__

Then, add an Event listener to

the element

<div id="topBar">

<p>Hello!</p>

</div>

<script>

const topBar = document.getElementById('topBar');

topBar.addEventListener("click", () => {

console.log("Hello there!");

});

</script>

JS has quite large amounts of built in events for different kind of user interactions.

A list of these can be found in:

[https://developer.mozilla.org/en-US/docs/Web/Events](https://developer.mozilla.org/en-US/docs/Web/Events)

and

[https://www.w3schools.com/jsref/dom_obj_event.asp](https://www.w3schools.com/jsref/dom_obj_event.asp)

Forms and JS example

<form id="login">

<label for="username">Username:</label>

<input type="text" name="username" id="username"/>

<label for="password">Password:</label>

<input type="password" name="password" id="password"/>

<button type="submit" id="login_button">Login</button>

</form>

const loginForm = document.querySelector("#login");

loginForm.addEventListener("submit", (e) => {

e.preventDefault();

const username = document.querySelector("#username");

const password = document.querySelector("#password");

console.log("username: ", username.value);

console.log("password: ", password.value);

});

Event listener fires when form is submitted. The script selects username and password inputs and logs the values

# Exercise 2: Counter

Add a button to your page. Add an event handler function to the button that uses the window.alert method to tell the user how many times they've clicked on the button so far.

See  [https://developer.mozilla.org/en-US/docs/Web/API/Window/alert](https://developer.mozilla.org/en-US/docs/Web/API/Window/alert)

For example, on first press the user should see a message box saying "Clicked 1 time(s)", on second press it should say "Clicked 2 time(s)", and so on.

_Note:_  _ _ In real life, avoid using window.alert as it's generally not great for the user experience. Here it's fine for educational purposes.

Exercise 3: Color change click!

Create an HTML element whose color changes when it's clicked.

First, use the fast "onclick" version

Then, convert it into using addEventListener

_Extra: _ Change the color of  _another_  element, not the one that was clicked!

_Extra 2: _ Change the color into a new random color every time the button is clicked!

# Strict mode

* __Strict mode__  was introduced in ES5
* Strict mode  __makes a few changes__  to normal JS semantics
  * Prohibits some JS syntax
  * Creates error logs for silent JS errors (that do not show up in the console)
  * Allows optimization of JS code
  * Strict mode is on automatically when using JavaScript modules i.e. using import and export

Converting your JS files to strict mode

* Make the first line of your code 'use strict'
* It prevents you from creating code that is considered bad practice:
  * Declaring variable without a keyword (let, const, (or var))
  * Using the "with" statement (we won't get into that, don't use it)
  * Using "delete" on a variable
  * Declaring functions in blocks:
  * and so on…
  * [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)

if (q===w) 	 _function_  f() {}

# Window

__window__  is an object that contains a set of default variables and functions that you can use within a browser

window.alert(), window.document, window.console.log(), window....

As you can see, most of these functions look familiar. That's because you can access them also without window.

In some sense, window keyword is just a list of global variables and functions.

Be careful with window!

Basically...

window.console.log("asd") --> console.log("asd")

window.alert("asd") --> alert("asd")

If you give a variable or function a name that is already used within the "window" object by default, that  __variable/function gets overwritten!__

# Separating scripts

Separating JS from HTML completely

Instead of including JS in the HTML file, we can separate it to another .js file

Then, we can refer to the new JS file in our HTML file:

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

There can be more than one of these links, e.g.,

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

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

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

_Note that the order of the script links matters!_

Multiple js files

* If we have multiple JS files, loading the page can get visibly slower
  * Adding a defer="defer" argument enables files to be  __loaded as resources get freed (=faster!)_
  * Still, the files will get executed in the correct order!
* <script src="someFunScripts.js" defer="defer"></script>
* <script src="bestScripts.js" defer="defer"></script>
* <script src="main.js" defer="defer"></script>
* _About file order:_  load more general stuff first, and the most specialized stuff last.
* It's also clearer if you make function calls in the  __last script only__ , and only  __declare __ stuff in the earlier scripts.

# Extra: Executing JS on page load

To execute script when the page loads, you can do this:

In your script.js file, you can define a function called, say, load()

then set it as a value of window.onload

function load() {

console.log("page loaded!");

}

window.onload = load;

# Exercise 4: Greeting the user

Separate your scripts into script files and link them to your main page.

Create a new file user.js

Into the new file, add a function that changes text on the page to a personified greeting "Welcome, [username]!

Run the function when the page is loaded.

Run the function again when the user submits a new username with a form!

# Dynamic CSS

# More about CSS classes

HTML elements can have multiple class attributes separated with a space<button class="btn btn-red">Submit</button><button class="btn btn-blue">Cancel</button>

__Applies to both buttons__

.btn {

border: none,

}

__Applies to__  __ __ .btn-red

.btn-red {

background-color: red;

}

__Applies to __ .btn-blue

.btn-blue {

background-color: blue;

}

# ClassList

In JS,  __classes can be added and removed__  dynamically with classlist (array-like object):

const button = document.querySelector(".btn-red");

button.classList.add("btn-blue");

button.classList.remove("btn-red");

Or  __toggled__ :const anotherButton = document.querySelector("#another-btn");button.classList.toggle("btn-blue");

Changing the element style

We can change the style of an element by using its style property.

First we get the element:

const someEl = document.getElementById('someEl');

Then we can change the element's style:

someEl.style['font-weight'] = 'bold';

or

someEl.style.fontWeight = 'bold';

CSS visibility vs display

We can change an element's  __visibility __ by using the css "visibility" property. Basically meaning that we can either  __show or hide an element__  __.__  Let's first store a reference to the element in someEl variable

const someEl = document.getElementById('someEl');

Notice that  __display__  removes the element and its effects from the DOM

This  __frees up space__ , but the element is still visible in the source code

__Visibility __ only hides the element from the DOM,  __still reserving the space for it__

someEl.style.visibility="hidden";					someEl.style.display="none";

someEl.style.visibility="visible";					someEl.style.display="block";

Exercise 5: change styles on hover

Get a handle to the three different sections on your page and make them change color to yellow when you hover your mouse over them

![](imgs/4-js-in-html-and-dom_0.png)

---

Solutions: Solutions: https://buuttilab.com/bctjs/week3-html-css-js-dom/-/tree/master/lecture-exercise-solutions/hover

# Dynamic HTML

Inserting HTML using JS

JavaScript allows us to create HTML by  __saving HTML as a string__

let someHtml = "<div><p>Hello there</p></div>";

document.getElementById("someElementId").innerHTML = someHtml;

More often than not, we want to use  __template literals__  instead of quotations, since this will help us embed variables in to our HTML code

let someHtml = \`

<div>

<p>Hello there ${friend}</p>

</div>

\`;

Creating HTML elements by using JS

JS allows us to  __create new HTML elements __  __programmatically__  as well

This way of adding new HTML elements is less prone to typos than when using string literals

const pTag = document.createElement("p");

pTag.innerHTML = "I am some Html in a p tag";

document.getElementById("someDivForExample").appendChild(pTag);

OR

const text = document.createTextNode("I am text node to append");

pTag.appendChild(text);

document.getElementById("someDivForExample").appendChild(pTag);

Removing a HTML element by using JS

Similarly, we can also  __remove __ an element from DOM

const post = document.getElementById("someElementWeWantToRemove");

const posts = post.parentElement;

posts.removeChild(post);

Alternatively, we can remove the  _n_  __th child__  from a parent like this:

const posts = document.getElementById("list_of_posts");

posts.removeChild(posts.childNodes[n]);

# DOM

![](imgs/4-js-in-html-and-dom_1.png)

Wikimedia Commons

__HTML DOM__  (Document Object Model) is the  _tree structure_  of the web page

it's created when the web page is opened

JS can modify all elements within the DOM

__DOM elements are objects__ , which have a range of different methods and properties

document.getElementById("idname").innerHTML;

_getElementById_  _()  _ _ is a  __method__ , innerHTML _ _ is a  __property__

Hint: We can access element attributes with method getAttribute()

# Exercise 6: event listeners

Create a simple user interface that displays jokes. Create four buttons and event listeners for:

Displaying one random joke

Displaying one random nerdy joke (category: nerdy)

Displaying all jokes

Deleting the first joke

Jokes array can be found on  [Gitea](https://gitea.buutti.com/education/academy-assignments/src/branch/master/Front-end%20Basics/4.%20JS%20in%20HTML%20&%20DOM/jokes.js) .

---

Default joke array and solution: https://buuttilab.com/bctjs/week3-html-css-js-dom/-/blob/master/lecture-exercise-solutions/jokes/main.js

# Chrome Dev Tools

* The most important tools of a modern web developer are bundled with the browser!
* Open the _ Inspect _ menu with
* _F12_  or  _CTRL+SHIFT+I_
* right-click the webpage and click Inspect
* Inspect has multiple tabs
* Most used ones: _ _
  * _Console_ ,  _Network_ ,  _Application_ ,  _Elements, Toggle._

![](imgs/4-js-in-html-and-dom_2.png)

# Console

_Browser has its own _  _Console_

_one of the most important tools for a front-end developer_

_e.g., app's error messages, console.logs and failed requests are printed here_

![](imgs/4-js-in-html-and-dom_3.png)

* In  _Elements_  you can browse and edit the HTML structure of the webpage
* easily demonstrate different styles in the browser
  * move the edits into code editor
* The internal structure of ready-made UI components get exposed here

![](imgs/4-js-in-html-and-dom_4.png)

* _Network_  exposes the data traffic (HTTP!)
  * the requests the page is sending to the server, and their responses
* Helps e.g., in the optimization of page load time
  * You can see which elements load slower!
* you can check  _Disable cache_  to make debugging easier (no previous data influences the current state of the web app!)
* check  _Preserve log_  to keep the console log intact when the page is reloaded

![](imgs/4-js-in-html-and-dom_5.png)

_In _  _Application_  _ you can track and manage e.g.,_

_Local Storage_

_cookies_

_tokens_

![](imgs/4-js-in-html-and-dom_6.png)

# Toggle

* _Toggle_  is used for designing responsiveness of webpages
* How would the page look on…
  * different resolutions
  * phones, tablets, etc…

![](imgs/4-js-in-html-and-dom_7.png)

![](imgs/4-js-in-html-and-dom_8.png)

Exercise 7: Let's mess around

Go to some random news page and change a headline into something silly with the Dev tools. (It's surprisingly easy!)

![](imgs/4-js-in-html-and-dom_9.png)

# Assignments

[Assignments about this topic can be found here](https://gitea.buutti.com/education/academy-assignments/src/branch/master/Front-end%20Basics/4.%20JS%20in%20HTML%20&%20DOM)

