Skip to content

Instantly share code, notes, and snippets.

@dominikkaegi
Last active April 3, 2020 14:23
Show Gist options
  • Save dominikkaegi/6260126e9adf326f71f640ef0bb9342b to your computer and use it in GitHub Desktop.
Save dominikkaegi/6260126e9adf326f71f640ef0bb9342b to your computer and use it in GitHub Desktop.

Javascript Course

General Inputs

Additonal Content on JavaScript

  • Mozilla Developer Network (MDN) to look up documentation for javascript.

  • Just Javascript an e-mail based "course" on the mental model behind Java Script from Dan Abramov. About one e-mail a day until you caught up and then one email every other week or so.

  • You don't know JS, a book series on Java Script which goes into great detail on how javascript works. All the books are available free online. These books are very technical, so they are not the easiest read, but will make you learn a bunch about JS.

Topics for this week

JS Concepts

  • Values
  • Types
  • Operations
  • Variables
  • Functions
  • Arrays
  • Loop
  • Decisions / Conditionals
  • Objects
  • Asynchronous Programming

Browser Concepts

  • Basic HTML
  • Basic CSS
  • DOM
  • Elements
  • Scripts to interact with the browser

General Agenda

  • Introduction
  • Kahoot Quiz
  • Topics of the day
    • Topic A
    • Challenges Topic A
    • Topic B
    • Challenges Topic B

Setup

We need the following tools for this course:

Running JavaScript

To run JS we need a "Runtime Environment", e.g. an environment in which we can run JS. There are multiple runtime environments out there, but the two most popular are NodeJS and the Browsers. NodeJS is used to run javascript on a server (e.g. on your local machine in a terminal). And then there are the different browsers in which you can JS.

For now we will use the Browser and runJS. RunJS is a small scratchpad application that lets you run JS and immediately evaluate it.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Our First Page</h1>

    <!-- All ways put your javascript at the end of the page because of loading order -->
    <script>
        console.log('Running Javascript')
    </script>
</body>
</html>

Variables

Declaring Variables:

There are three ways to declare a variables:

var name = "dominik"
let age = 26
const sex = "M"

var and let allow for reassignment of the value. const does not allow to reassign the value.

// var and let can be changed
name = "Susie"
age = 27

// const can not be updated
sex = "F" // Uncaught TypeError: Assignment to constant variable.

What to use? var, let or const? (opinionated)

Which way should you declare your variables? Well all ways to declare a variable are valid, but one common opinionated view is:

  1. Always use const, because often you don't know if you will reassign a value
  2. If you get an error because you reassign a variable, then move to let

Naming Conventions

A variable name can start with a letter e.g. a-zA-Z or one of the special characters underscore _ or a dollar sign $. Starting a variable with any other character will throw an error.

const girl = "sara"
const _girl = "sara"
const $girl = "sara"

const 1girl = "sara" // Uncaught SyntaxError: Invalid or unexpected token

Strict Mode

Since Javascript evolved a lot of time there are different versions of it. In our case, we want to use strict mode. The strict mode adds additional rules of how javascript can be written and we use it because it prevents us from declaring variables without a var, let or const. We can activate strict mode by adding use strict; at the beginning of our file.

"use strict";

const dog = "bello"
cat = "Garfield" // Uncaught ReferenceError: cat is not defined

Scope

There is a difference between var, let and const when it comes to scope. Scope refers to where we can access a variable. We will have a closer look at how scope works within this course but for now, we just leave you with this:

  • var are function scoped
  • let and const are block-scoped

Code Style

When we are coding in our IDE we can write the code pretty much however we please, as long as it is valid js. This means we can add spaces, or move all our code onto one line and it is still valid. However, this can make it harder to read our code. To keep our code style consistent we can use programs that help us with that. One of those Programs is Prettier. It is opinionated how the code should look like, but it helps us to keep our coded consistent and "pretty".

1. Download Prettier

Go to the extension pad within VS Code and search for the Prettier Extension

2. Use Prettier

We can now use prettier by activating it within VS Code. There is a shortcut in VS code if we want to execute any VS code commands:

  • Mac OS Shortcut: cmd + shift + p
  • Windos Shortcut: ctrl + shift + p
  1. Enter Short Cut
  2. Select Format Document With...
  3. Select Prettier

We can also run prettier every time we save the file by changing the settings:

  1. Short Cut
  2. Preferences: Open Settings (UI)
  3. Search for "Format On Save"
  4. Activate Format on Save

Types

Primitive Types

  • String
  • Number
  • Boolean
  • Null
  • Undefined
  • Symbol

Non-Primitive Type

  • Object

Finding the type of a value

We can figure out the type of a value by using the typeof operator on a value. But there are some caveats with it. Let's have a look at them.

typeof 200                    // "number"

typeof "Hi there!"            // "string"

typeof true                    // "boolean"

typeof undefined            // "undefined"

typeof null                 // "object" (a historical bug)

typeof { name: "jim" }        // "object"

typeof [1, 2, 3]             // "object" (array is subtype of object type)
                            // There are other operations to figure out if it is an array
                            
typeof function add(a,b) {
    return a + b
}                            // "function", function is a subbtype of the object type
                            

Strings

Strings are used to save text in variables. There are three ways to define a string in javascript, single quotes ', double quotes "" and backticks `

const name = "Dominik"
const middle = 'Robin'
const last = `Kägi`

Single quotes and double quotes have the same functionality. We have both to construct sentences with apostrophes:

// sample needs an escape character for the '
let sample = 'he\'s the sun of the mayor'

// or we need to use double quotes 
let sentence = "he's the son of the mayor"

// Multiline Strings
let multilineAttempt = 'jimmy \
what is up \
it is kind of hot here'

let multiline = 'jimmy \n what is up \n it is kind of hot here'

// Using Variables
const name = "Jimmy"
const age = 20
let biography = name + " is " + age +  " years old"

Backticks allow using all the features above in a more compact syntax. With Backticks we can create multiline strings and embed variables within the string.

const name = "Jimmy"
const age = 20

const biogrpahy = `
    ${name} is ${age} years old
`

Tasks:

1. Creating a String

Create a variable name and assign it to your name. Log the result to the console. Check if it is a string with the typeof operator.

2. Concatenating Strings

Create a variable jimmyIs with the value "Jimmy is " and then create three more variables with the values "happy", "beautiful", "strong". Then create three full sentences by concatenating the jimmyIs variable with the adjective variables.

const jimmyIs;
const happy;
const beautiful;
const strong;

const sentence1;
const sentence2;
const sentence3;
  1. Did you use single quotes, double quotes or backticks to create the strings?
  2. What did you use to concatenate the different strings? The + operator or backticks with ${} ?
  3. Find a new way to concatenate strings which you have not seen so far in the course on the internet

3. Multiline String

Create the multiline string below with backticks and without backticks. Replace the values of name, street and city in the string with the variables defined up top for the string with and without backticks.

const name = "Jimmy Cool"
const street = "Holly Wood Boulevard 255"
const city = "Los Angeles"


// Make this a valid string:
let data = "
    Name: Jimmy Cool
    Street:    Holly Wood Boulevard 255
    City: Los Angeles
"

Numbers

Common Operations

There is just one type of number in JS and it is number. Although we can have integer numbers and floating-point numbers, they both just have the type number.

There are all the common operations existing for numbers.

let a = 5
let b = 10

// add
a + b                // 15
// multiply
a * b                // 50
// divide
a / b                // 0.5
// subtract
a - b                // -5
// modulo
a % 5                // 0

Operations on different types

When we do these kinds of operations we can get some unexpected results if we end up doing operations on different types. So we want to be careful to use the same types when operating on them to spares us these potential bugs.

10 + "20"        // "1020"

"10" + "10"        // "1010"

10 * "10"        // 100

"10" * "10"        // 100

Math Module

In JS there is also a built-in Math module which we can use for different calculations. That's how we can use it:

Math.round(5.5)        // 6
Math.round(5.4)        // 5

Math.floor(5.55)    // 5

Math.ceil(5.55)     // 6

Math.random()         // 0 <= num < 1 

Math.PI                // 3.141592653589793

Floating-Point Numbers

As with every language, javascript also has some problems when it comes to floating-point numbers.

0.1 + 0.2        // 0.30000000000000004

// learn more on http://0.30000000000000004.com/

This can cause certain problems in the real world. For example, if we would want to charge somebody two items in an online store which both have a price in floating-point numbers we could end up trying to charge them some minuscule amount. In this case, it is better to just convert the floating-point numbers into integers by multiplying them by 100, e.g. move from dollars to cents.

let price = 1.59            // Dollars
let savePrice = 159             // Cents

Infinity

In javascript, there exists Infinity which gets displayed if the result of a calculation is too big.

10 / 0            // Infinity
-10 / 0            // -Infinity

NaN - Not a Number

When we use invalid operations on Numbers we get NaN as a result. NaN stands for "not a number" and is in itself a value. We can check if a value is not a number by using the isNaN function. The typeof NaN is "number".

let result = 50 / "blue"        // NaN

isNane(result)                     // true

typeof NaN                        // "number"

Tasks:

1. Find floating point inaccuracies

Play around and add, subtract, multiply or divide two floating-point numbers until you find another surprising inaccurate result. If you don't manage to find a number within 2 to 3 minutes just move on to the next task. There is a little bit of luck involved in finding another number.

// Example:
0.1 + 0.2        // 0.30000000000000004

2. Create a random number between 1 and 100

Use the Math.random() method to create a random number between 1 and 100. You will probably need another method from the Math module to make the number an integer.

let randomNumber = 'your calculation'

3. Create NaN

We heard about the NaN value which is the result of invalid operations. We received the NaN value by dividing a number by a string. Find another operation which results in the NaN value.

let result = 50 / "blue"        // NaN

4. Feeding Cookie Monsters

  • If you distribute 1090 cookies to 39 cookie monsters, how many cookies will each cookie monster get? We won't break up any cookies.

  • How man cookies will remain after distributing all the cookies evenly?

Objects

Objects are the biggest building block in JavaScript. Pretty much anything which is not one of the other types is an Object in JS. Generally, we use the most part object to store any kind of data. Objects allow us to create a collection of data and functionality. For example Arrays, Dates and Functions are also objects. We use objects to group things together.

There is a big difference between objects and all the other values we have seen so far. The other values are all primitive values, objects, on the other hand, are non-primitive type, or also called reference type. What does that mean?

let name = "Dominik"
let age = 20
let profession = "Teacher

// defining an object with properties
let person = {
    name: 'jimmy',
    age: 20,
    profession: 'Programmer'
}

// accessing properties
let name = person.name
let age = person.age
let profession = person.profession

A variable that points to a primitive type works differently to a variable that points to an object reference. When we change the value of a primitive type, the arrow from the variable to the value changes. If we change the value of an object, we don't change the reference to the object, but we change the arrow of the given property on the object to a new value.

// Primitive Types
let name1= 'Jimmy'
let name2 = name1
name2 = 'Tom'

console.log(name1)    // 'Tom'
console.log(name2)    // 'Jimmy'


// Non Primitive Type
let person1 = {
  name: 'Jimmy',
}

let person2 = person1
person2.name = 'Tom'

console.log(person1)    // { name: 'Tom' }
console.log(person2)    // { name: 'Tom' }

Tasks

1. Using Objects

  • Define a vehicle object which following properties and assign it to the variable vehicle1
type: "SUV"
brand: "Mercedes"
amountOfWheels: 4
topSpeed: 200
litersPer100km: 12
  • Draw a sketch representation of your vehicle either on paper or excalidraw.

  • Log all the different properties the vehicle has to the console

  • Create a second object, with the variable name vehicle2 that has the same properties as vehicle1, except it has a topSpeed: 160 and a litersPer100km: 8.

Null and Undefined

There are two ways to define "nothing", null and undefined. When we declare a variable but not assign it any value, it gets the default value undefined. So undefined is a value for variables that have not gotten a value assigned to it.

let name;
console.log(name)        // "undefined"
name = "Jimmy"
console.log(name)        // "Jimmy"

We also get undefined if we want to access a property on an object which has not been declared.

let person = {
    name: 'jimmy',
    age: 20,
    profession: 'Programmer'
}

let sex = person.sex        
console.log(sex)            // "undefined"

As opposed to undefined the null value has to be assigned to a value. So if you find a null value somewhere in your program either you or a fellow programmer of yours assigned that value to the variable. When programming we use the null value to explicitly express that the value should be empty.

let myUndefined;
let myNull = null;

Tasks

Think through the different code snippets and try to figure out what the result is. Once you decided for an answer, run the code snippet and see if you were right.

  • What types are the variables x and y?
let x;
let y = 50;

console.log(typeof x)
console.log(typeof y)
  • What is the type of length?
let car = {
    brand: 'VW',
    weigth: 1460
}

let length = car.length
console.log(typeof length)
  • What is the type of length?
let car = {
    brand: 'VW',
    weigth: 1460
}

let length = car.brand.length
console.log(typeof length)
  • What is the value of length?
let car = {
    brand: 'VW',
    weigth: 1460
}

let name = car.owner.name
console.log(typeof name)

Booleans

True or False

Booleans are values which hold truth within themselves. They can hold the value false or true. We can also think of them as either 0 or 1 as values. They are basic building blocks which we will use all over our programs.

We use booleans in particular when we start adding more logic to our programs and use flow control (e.g. if and else etc.). For example, you have some kind of flag variable isSubmitting on a form:

let isSubmitting = true

As long as the value isSubmitting is true you want to make sure to display some kind of loading indicator to your user. As soon as the submission of the form data has been accepted by your backend server, we can set isSubmitting to false and stop displaying the loading animations.

Operations

We can also calculate booleans. For example, we can check if one value is bigger than the other.

let isTenBiggerTwent = 10 > 20    
console.log(isTenBiggerTwent)        // false

let isHundredBiggerTen = 100 > 10
console.log(isHundredBiggerTen)        // true

And then there are operations specific to booleans such as AND, OR and NOT.

let age = 16
let isAllowedToDrinkBeer = age >= 21
let hasCash = true

let receivesBeer = isAllowedToDrinkBeer && hasCash
console.log(receivesBeer)  // true

false && false        // false
false && true        // false
true && false        // false
true && true        // true

false || false    // false
false || true   // true
true || false   // true
true || true    // true


!false    // true
!true     // false
!!false   // false
!!true    // true

!(true || false)        // false

AND Operator

&& true false
true
false

OR Operator

|| true false
true
false

NOT Operator

! true false

Equality Signs in JS

In javascript we use the equality sign in three different ways, single =, double == and triple ===. Each of them has different functionality. The single equals are used to assign a value to a variable. The double and triple equals are used to check for equality but they do check for equality differently. Before going into the details, in almost all cases you want to check for triple equality === instead of double ==. So what's the difference.

// single equals for  assigning values
let clothSize = "10"
let personSize = 10

// double equals to check for equality with type coersion
let doesFit1 = (clothSize == personSize)
console.log('double equals: ', doesFit1)         // true

// tripe equals to check for equality without type coersion
let doesFit2 = (clothSize === personSize)
console.log('triple equals: ', doesFit2)       // false

Double equals == changes the type of a value if necessary. If we compare the string "10" and the number 10 coerces the type and receives a truthy value as a result.

The triple equals === on the other hand does not type coercion and thus it receives a falsy value. You can think of === as doing the following:

let a = "10"
let b = 10
let isSame = typeof a == typeof b && a == b
console.log(isSame)        //false

Tasks

  1. Explain in your own words the difference between =, == and ===

  2. Try to figure out what the result of each of these operations is. Once you managed to figure out what the result is, run the code and check if you were right.

// 1. 
true && true

// 2. 
true || false

// 3. 
!!true

// 4.
!!!false

// 5.
10 > 50

// 6.
15 >= 15

// 7. 
10 == 10

// 8.
10 == 12

// 9. 
10 === "10"

// 10.
null == null

// 11.
null === null

// 12.
undefined === undefined

// 13.
let car1 = { brand: 'fiat' }
let car2 = { brand: 'Fiat' }
car1 === car2

Functions

Functions in programming allow us to wrap up certain functionality (e.g. code we wrote) and make it reusable so that we don't need to write said code multiple times. It allows us to group sets of statements.

So how does a function look like? Let's have a look at it and the surrounding vocabulary.

Builtin Functions

In javascript, there are built-in functions that are readily available for our use. We already have seen some of them since they are so essential. Let's have a look at some of them.

console.log('hey there')

let age = prompt('What is your age?')

alert('WARNING: Critical Error from Microsoft')

let shouldContine = confirm("Are you sure you want to continue?")

Not all the functions exist in all run time environments. For example prompt, alert and confirm do only exist in the browser / DOM, they do not exist in NodeJS.

Let's have a look at some more built-in function which exists in the browser.

scrollTo(0,0)
scrollTo(0, 1000)
scrollTo({
    top: 1000,
    behavior: 'smooth'
})

history.back()
history.forward()

Let's have a look at some functions which exist not only in the browser.

parseFloat("20.05")        // 20.05

parseInt("26.05")        // 26

Math.random()

// https://epoch.now.sh/
Date.now()

Custom Functions

We can create our custom function by defining them with the function keyword. Let's try to create a function which encapsulates the console.log functionality and makes it shorter so that we can just call log if we want to print something out,

// Function Definition
function log() {
  // Function body
    console.log('log function is running')
}

// Function Call 
log('my result')

We first declare our function with the function definition. Within the function body, we added a console log, to make sure the code is running when we call the function. Now how can we log the string my result? We can add parameters to the function.

// Function Definition
function log(value) {
  // Function body
    console.log(value)
}

log('my result')

We call now the newly declared function with a parameter that is a string of value "my result".

Return Value of Functions

Every function always has a return value. That means when we execute a function, the function execution will return some kind of value. If we don't return a value from a function, per default 'undefined' is returned.

function add(a, b) {
  let result = a + b
} 

let executionResult = add(10, 20)
console.log(executionResult)

In the snipped, we received undefined as a result, because the function is not explicitly returning any value. We don't want to receive undefined, but the result of the function. For that, we need to add a return statement.

function add(a, b) {
  let result = a + b
  return result
} 

let executionResult = add(10, 20)
console.log(executionResult)

Parameter vs Argument

Let's have a look at parameter vs argument.

function add(a, b) {
  let result = a + b
  return result
} 

Here we have a function that has two parameters, the parameter a and the parameter b. Within the function, we have a statement that adds the two parameters together. Then the function returns a value, which is result.

We can execute a function and by passing on some data, that data is called arguments.

let result = add(10, 20)
 console.log(result)        // 30

result = add(10, 50)
console.log(result)        // 60

result = add("Hello ", "World!")
console.log(result)        // "Hello World!"

The difference between arguments and parameters is that we define parameters for a function during the function declaration. When we execute a function we pass on arguments.

Arrow Functions

There is a second way we can define functions and those are called arrow functions. Arrow functions are a shorter form to define functions. It is up to you to use one or the other

// Arrow function with no arguments
const arrowFunction = () => {
  console.log('running arrow function')
}

// Arrow function with two arguements and long function body
const add = (a, b) => {
    return a + b
}

// Arrow function with two arguments and short function body
const divide = (a, b) => a / b

// arrow function with one argument and short function body
const addTwo = a => a + 2

Tasks

1. Greet User

Create a function that:

  • Ask the user for his name (prompt)
  • Uppercases the user's name
  • Greets the user with his name in uppercase (alert)
"dominik" -> "Hi DOMINIK!"

2. Years until 100

Create a function that:

  • Ask the user for his age (prompt)
  • Calculates how many years it will still take until the user is 100 years old
  • Alert the user of how many years until he is 100 years old

3. Geolocation

Create a function that logs the geolocation to the console. The browser provides an API to access the geolocation of a user. Search for it on MDN.

Execution context

The execution context consists of the

  • thread of execution: goes through each line and executes line by line
  • memory: saves data that has been created during the thread of execution.
const num = 3

function addTwo(input) {
  const result = input + 2
  return result 
}

let output = addTwo(5)
let newOutput = addTwo(10)

Execution Context

Callstack

Tasks

1. Line by Line

Sketch out what happens when executing the code below "line by line" on a notepad or excalidraw. Make sure you draw the thread of execution, the memory, and the callback stack.

const numberOfRuns = 3

function milesToKM(miles) {
  let result = miles * 1.60934
  return result
}

let firstRun = milesToKM(5)
let secondRun = milesToKM(10)

Scope

A telescope lets us see stars up close and depending on what kind of telescope we have we can see further in the distance and see more stars in the sky.

In JS the scope defines which stars we can see, or to put it in other terms which variables we can access and thus which values we can access. In particular, there are two scopes in javascript, block scope and function scope.

Block Scope

A block in JS is code which is surrounded with curly braces {}.

// empty block
{

}

You can add such blocks wherever you want within your code.

var x = 20;

{
    var y = 30;
}

function add(a,b) {
  let result
  
  {
    result = a + b
  }

  return result
}

But whenever you introduce a block, you create a block scope and variables which are block-scoped won't be accessible outside the scope. All variables which are defined with let or const are block-scoped. Let's have a look at some code examples:

{
    var a = 10
    let b = 20
    const c = 30
}

console.log(a) // 10
console.log(b) // ReferenceError: b is not defined
console.log(c) // ReferenceError: c is not defined

When we run the code, we can access the variable a outside of the block scope. For the variables b and c we get a reference error, because they don't exist in the global scope and thus we get a referenceErorr, that the variable is not defined.

Function Scope

Function definitions create scopes as well. Let's have a look at a function.

function () {
    // function body
}

Any variables defined within a function are function scoped. We can not access variables that are defined within a function outside of the function.

function myFunc(y) {
    var a = 10
    let b = 20
    const c = 30
}

console.log(a) // ReferenceError: b is not defined
console.log(b) // ReferenceError: b is not defined
console.log(c) // ReferenceError: c is not defined

myFunc(10)
console.log(y) // ReferenceError: y is not defined

Because of the different scopes we commonly say let and const are block-scoped and var is function scoped. But every block-scoped variable is also function scoped because function scope is more restrictive than block scope.

Tasks

For each of these code blocks, think through what will be logged. Once you figured it out, run the code to evaluate.

// 1.
let a = 10
{
  a = 20
}
console.log(a)
// 2.
let a = 10
{
  let a = 20
}
console.log(a)
// 3.
let a = 10
{
  let a
  console.log(a)
}
// 4.
let a = 20

function change() {
  a = 40
}

change()
console.log(a)
// 5.
let a = 20

function addTwo() {
  a = 40
}

console.log(a)
// 6.
let a = 20

function addTwo(a) {
  return a + 2
}

addTwo(a)
console.log(a)

Hoisting

Hoisting allows you to access functions and variables before they have been created.

Function Hosting

When we declare a function we can access it before we declared it within our code.

let result = add(20, 30)
console.log(result)

function add(a,b) {
  return a + b
}

We can think of javascript rearranging our code to this:

function add(a,b) {
  return a + b
}

let result = add(20, 30)
console.log(result)

And thus it makes sense to be able to access and execute the function.

Variable Hosting

Variables declared with var are also hoisted. This means we can access the variable before we declared it, it will just be undefined.

console.log(name)
var name = "dominik"

You can think of the code above to being rearranged to this code below. Thus we can access name, but it does not have it's value yet.

var name;
console.log(name)
name = "dominik"

The variables declared with let and const are not hoisted.

console.log(name)
let name = "dominik" // ReferenceError: Cannot access 'name' before initialization

Tasks

// 1.
console.log(num)
var num = 20

// 2.
console.log(age)
let age = 30

// 3.
console.log(name)
const name = "jimmy"

// 4.
sayHello()
function sayHello() {
  console.log('hello')
}

// 4.
console.log(sayBye)
function sayBye() {
  console.log('hello')
}

Conditionals / Control Flow

Conditional allows us to have some kind of flow in our application and execute different code, depending on the truthy value.

Let's have a look at a control flow statement or such an if statement.

if(true) {
    console.log('it is true')
}

We can also add an else flow, for code we want to run if the if state has not been fulfilled.

let panda = {
    name: 'Pummelbear',
    age: 5,
    isAwake: true
}

if(panda.isAwake) {
    console.log('The panda is awake')
} else {
    console.log('The panda is asleep')
}

Lastly, we can add else if statements, to check for multiple

let x = 10
if(x === 10) {
    console.log('x is 10')
} else if (x > 10) {
    console.log('x > 10')
} else {
    console.log('x < 10'
}

Tasks

  • Guessing Game

We want to create a guessing game. The guessing game should do the following:

  1. When we start the game the game should set a random number between 1 and 20 as the target, the number which the user should guess.

  2. After setting the target, it asks the user to guess a prompt. Then the game gives feedback concerning the guess.

    • If the guess is correct, notify the user that he managed to figure out the number and tell him how man guesses he needed to figure out the correct number
    • If the guess is too low, let the player know that the number is too low and give him another chance to figure out the target
    • If the guess is too high, let the player know that the number is too high and give him another chance to figure out the number
    • The player wins the game if he manages to figure out the result in 5 guesses or less
  3. Once the player won or lost the game, ask the player if he would like to play a game and restart the game if needed.

Loops

for(let index = 0; index < 10; index++) {
    console.log(index)
}

Arrays

// Initialising and empty array
let newArr = []

// Initialising Array with Values
let numbers = [10, 20, 30, 40]

// accessing a value
numbers[0]

// acessing a value which does not exits
const value = numbers[40] 
console.log(value) // undefined

// setting a value
numbers[0] = 30
numbers[1] = numbers[1] + 5

// Adding value to array
let names = ["jim"]
names.push("tom")
names.push("lisa")

// Removing the last value
let lisa = names.pop()

// Arrays can continue any value  
let mixedArray = [
  "Dominik",
  20,
  { country: "switzerland" },
  function () {
    console.log("hello");
  },
];


// Accessing the length of an array
console.log(arr.length)

Tasks

  • Multiply all numbers by 2
let numbers = [10, 20, 30, 40, 50]
  • Create an Array which contains all numbers from 0 to 100
let numbersTill100 = [ ]

HTML

The basic structure of an HTML file.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document Title</title>
</head>
<body>
  
</body>
</html>

We can add a multitude of elements into our HTML. A couple of examples

  • div
  • h1
  • p
  • img

Inline Elements vs Block Elements

There are certain elements in HTML that take up a full block and force the nest element onto a new line. Those elements are called Block Elements and are elements such as div, h1 and p (MDN Block Elements).

Then there are inline elements that don't force the next element on a new line. Example for these are span, input or a (MDN Inline Elements).

Task

Recreate the page below.

  • For pictures you can use picsum, it will give you a random picture every time you reload the page. Add it as the src on your <img /> tag like this <img src="https://picsum.photos/200" />.
  • Make sure the link of "Google Might Help!" opens a new tab within the Browser

CSS

  <style>
      <!-- Tag Selector -->
    div {
      padding: 20px;
      background: pink;
    }
    <!-- Class Selector -->
    .item {
      padding: 10px;
      background: green;
    }
    <!-- Id Selector -->
    #id {
      font-size: 100px;
    }
  </style>
  <div>
    <h1 id="title">CSS is Great</h1>
    <p class="item">
      Lorem Ipsum
    </p>
    <p class="item">
      Lorem Ipsum
    </p>
    <p class="item">
      Lorem Ipsum
    </p>
  </div>

Task

Let's add some styling to our previous website to make it look like the page below. Add some styles to your previous website. If needed add some id or class properties to your HTML file. Make sure to use at least one tag, one class and one id selector in your CSS.

If you don't have the HTML at hand from the previous task feel free to use the HTML provided below.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My First Website</title>
</head>
<body>
  <div>
    <h1>My First website</h1>
    <p>I'm super exited</p>
    <img src="https://picsum.photos/400" />
    <p>
      Not finding what you are searching for? <a href="https://www.google.com/" target="_blank">Goggle Might Help!</a>
    </p>
    <p>
      Thanks for passing by. Hope to see you again!
    </p>
  </div>
</body>
</html>

DOM

The Document Object Model (DOM) connects web pages to scripts or programming languages by representing the structure of a document—such as the HTML representing a web page—in memory.

The DOM represents a document with a logical tree. Each branch of the tree ends in a node, and each node contains objects. DOM methods allow programmatic access to the tree. With them you can change the document's structure, style, or content.

In the DOM we also have a scope, and that scope is prefilled with different objects and values.

Window

The global scope in the browser is called the window. The window is an object where all global variables we define are stored as well a lot of useful properties.

If we add a var variable in the console of the developer tools, we will be able to find it on the window object.

var name = "dominik"

window.name

There are a lot of other useful, for example when we looked at the code of how to get the GPS location of the user yesterday, we user navigator, which is one of the properties of the window. You can find an extensive list on MDN.

window.navigator.geolocation

Document

The document is an object which is on the window and it is a representation of all the HTML in object form. If we want to add any kind of interaction with the browser we add scripts that interact with the document.

document

Selecting Elements from the document

// select the first h1 element
let h1 = document.querySelector("h1")

// select the first element with class item
let item = document.querySelector(".item") 

// select the first element with id "title"
let item = document.querySelector("#title") 

// select the first p element within the first div
let p = document.querySelector("div p")

// Select all p elements
// Returns a node list.
let paragraphs = document.querySelectorAll("p")

// Changing 
let firstDiv = document.querySelector("div")
let firstP = firstDiv.querySelector("p")


// Get Elements
let idElement = document.getElementById("my-id")

Element Properties

A full list of all properties of an element can be found on the MDN Element Docs

let h1 = document.querySelector("h1")
console.log(h1)
console.dir(h1)

h1.textContent = "New Title"
h1.innerHTML = `<span>Title with span</span>`

Selecting Elements Task

For all the task please use the HTML provided at the end of the task.

  1. Select the h1 by its id and change the text of it to "New Title"

  2. Change the text from the third paragraph to say "Bye Bye"

  3. Change the document title (e.g. "Awesome Website") to "Beautiful Website".

  4. Change the image which is being displayed to a different image of your liking.

  5. Browse the documentation of dom elements for a couple of minutes and play around with some properties. Did you find anything interesting?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Awesome Website</title>

  <style>
    body {
      font-family: sans-serif;
    }

    #title {
      color: grey;
      letter-spacing: 0.5rem;
      text-transform: uppercase;
    }

    div {
      background-color: #e2e8f0;
      padding: 40px;
      width: 500px;
    }

    .paragraph {
      /* font-size: 10px; */
    }

  </style>
</head>
<body>
  <div>
    <h1 id="title">My First website</h1>
    <p class="paragraph">I'm super exited</p>
    <img src="https://picsum.photos/400" />
    <p class="paragraph">
      Not finding what you are searching for? <a href="https://www.google.com/" target="_blank">Goggle Might Help!</a>
    </p>
    <p class="paragraph">
      Thanks for passing by. Hope to see you again!
    </p>
  </div>
</body>
</html>

Change Image Task

Create a function that selects all img elements on a website and changes them to an image of Mr. Beans face.

function changeImages() {
    // your code
}

Bookmarklets

A bookmarklet is a bookmark stored in a web browser that contains JavaScript commands that add new features to the browser.

We can't use the plain javascript and just add it to a bookmarklet. We need to add a tag a serialize certain characters because we, for example, can't have any spaces in a URL.

Task:

Convert your function changeImages() from the previous task to a bookmarklet and add it to your browser.

Event Listeners

We can add Event Listeners to an element of the document tree. When the user interacts with the browser and triggers our event listener, our function which we provided for that event will be called.

Here is an example of how we can add an event listener to a button which listens for a click event:

  <body>
    <button>Awesome</button>
  </body>
const btn = document.querySelector("button")
  
function handleClick() {
	console.log('You are awesome!')
}

btn.addEventListener('click', handleClick)
  
btn.removeEventListener('click', handleClick)

We can find a full list of all different kinds of events on MDN Events.

Image Change on Hover

Add an event listener to each image within the web page which listens when to the mouse hovers over the element. If the mouse hovers over an image, change the image to a picture of Mr. Bean.

Playback Speed

We want to add functionality to our page with which we can change the playback speed of videos on a keypress because some times the normal speed of a video is just not fast enough.

  • Add to event listeners to the document which listens to the keypress of s and d
  • If d has been pressed, increase the playback speed of the video by 0.1.
  • If s has been pressed, then decrease the speed by 0.1.

Try to google to figure out how you could achieve this. If you don't get any further with googling you could have a look at this code. It might give you some hints on how to solve your problem.

Custom Attributes

HTML provides us with a list of different attributes we can use within the browser (MDN Attribute List). If we want to add any kind of custom attributes to the browser we need to use the data- prefix for that property.

<div>
    <p data-name="jimmy">Jimmy is cool</p>
</div>

Accessing custom properties on a DOM element.

let p = document.querySelector('p')

let properties = p.dataset  

Creating HTML Elements

We can create HTML elements with JavaScript and add them to the page.

// creating the element
let paragraph = document.createElement('p')

// modifying the properties of the element
paragraph.textContent = "Paragraph created with JS"


// Create a img element
let image = document.createElement('img')
image.src = "https://i.picsum.photos/id/153/400/400.jpg"


// Adding the element to the screen
document.body.appendChild(paragraph)
document.body.appendChild(image)

When appending multiple elements to the DOM we can run into some performance problems. Every time we add ane element to the dom, the webpage is being rerendered. So if we have multiple consecutive elements we add to the page we can multiple renders. A way to resolve the problems is to create one element (e.g. a div) and only add that div to the page.

let paragraph = document.createElement('p')
paragraph.textContent = "Paragraph created with JS"

let image = document.createElement('img')
image.src = "https://i.picsum.photos/id/153/400/400.jpg"

// Grouping Elements which need to be added to a page
let myDiv = document.createElement('div')
myDiv.appendChild(paragraph)
myDiv.appendChild(image)

document.body.appendChild(myDiv)

There is more than one way to insert elements into the DOM, as always MDN is your friend.

Task

Create an HTML list that has five todos in them. The HTML is only created by HTML. Add an id to each element in your list.

<ul>
    <li data-id="1"> Drink Water </li>
    <li data-id="2"> Workout at the GYM </li>
    <li data-id="3"> Cook Dinner </li>
    <li data-id="4"> Clean up room </li>
    <li data-id="5"> Water the plants </li>
</ul>

Removing HTML Element

Besides creating and adding elements to the page we can also remove elements from a page. To remove an element from the page we need to select the element with querySelector and then remove it from the page with the remove() method on that element.

<div id="div-01">Dies ist div-01</div>
<div id="div-02">Dies ist div-02</div>
<div id="div-03">Dies ist div-03</div>
var el = document.getElementById('div-02');
el.remove(); // Entfernt das div Element mit der id 'div-02'

Task

In the previous task, we created a list of todos. Our result looked like this:

<ul>
    <li data-id="1"> Drink Water </li>
    <li data-id="2"> Workout at the GYM </li>
    <li data-id="3"> Cook Dinner </li>
    <li data-id="4"> Clean up room </li>
    <li data-id="5"> Water the plants </li>
</ul>

Add an element listener to each todo element in the list. When we click on the element in the list, the list should be deleted from the HTML.

Forms

<form>
  <input name="todo" />
  <button type="submit">Add Todo</button>
</form>
// Adding Event Listener
let form = document.querySelector('form')
form.addEventListener('submit', function(event) {
    event.preventDefault()
    let val = form.querySelector('input').value
    console.log(val)
})

Task

Previously we build a list with todos and the option to remove a todo. Now we want to also add the option to add todos to the list. For that go ahead and add a form to your HTML in which a user can add a todo. The user should be able to enter a todo in text form and then click on a button to add it. Once the button is clicked, create a new todo element and add it to the list.

Options

  • Iterating over Arrays
  • Asynchronous Programing
    • Promises (Fetching Data)
    • setTimeout
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment