You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
504 lines
14 KiB
Markdown
504 lines
14 KiB
Markdown
# 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
|
|
|
|

|
|
|
|
---
|
|
|
|
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
|
|
|
|

|
|
|
|
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._
|
|
|
|

|
|
|
|
# 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_
|
|
|
|

|
|
|
|
* 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
|
|
|
|

|
|
|
|
* _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
|
|
|
|

|
|
|
|
_In _ _Application_ _ you can track and manage e.g.,_
|
|
|
|
_Local Storage_
|
|
|
|
_cookies_
|
|
|
|
_tokens_
|
|
|
|

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

|
|
|
|

|
|
|
|
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!)
|
|
|
|

|
|
|
|
# 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)
|
|
|