Lecture overview¶
- HTML/CSS Review
- What is JavaScript?
- The JavaScript language
- features
- JavaScript in the web browser
- accessing the DOM
- manipulating the DOM
- user interaction: events and event listeners
- JavaScript syntax
- control structures
- loops
- functions
- JavaScript Objects
HTML/CSS review¶
HTML - structure¶
- DOM (Document Object Model)
- Hierarchical document structure
- Element tags
<body>,<div>,<h1>,<span>, etc. - Element attributes, e.g.
src,href,class,id - Elements can contain other elements
CSS - style and layout¶
- Selectors: used to specify scope of declaration blocks
- HTML structure dictates which selectors can be useful
- Style: color, size, image positioning, typography etc
- Layout
display: block|inline|inline-block|flex|gridposition: static|relative|absolute|fixed|stickytop,left,right,bottommargin,paddingalign-items,justify-content(onflexparent)
- Extra tip: learn
gridlayout at https://cssgridgarden.com/
Validating your HTML and CSS¶
What is JavaScript?¶
Why the confusing name?¶
Story time¶
A Lisp for the web?¶
- Sometime in the 1980s, software developer Brendan Eich is given a copy of Hal Abelson's and Gerry Sussman's book Structure and Interpretation of Computer Programs and becomes passionate about the Scheme programming language, a dialect of Lisp created by Gerry Sussman and Guy Steele.
- Eich is recruited by Netscape's R&D department in February 1995 specifically to embed Scheme as a simple and light-weight scripting language in their Netscape Navigator web browser (which at the time held a 80-90 % share of the browser market).
- Before Eich actually starts his employment, Netscape's management makes a deal with Sun Microsystems to embed their new programming language, Java, in Navigator.
- Netscape management decides to cancel Eich's project since they've already decided on Java.
Java and only Java?¶
- Netscape R&D staff are unhappy with Java and argue that it is too complex for many applications.
- Java might work for component authors, professional programmers who build plugins and "applets" that can be used to build dynamic web pages.
- Actual web designers (whether amateur or professional) need a more light-weight "glue language" to assemble such components and integrate them with HTML.
- Management reluctantly agrees, but request that the language "looks like Java" while not risking their good relations with Sun by competing against Java. Most specifically, the new language can't have classes.
- Eich is given 10 days in May 1995 to deliver a functional (or rather, functioning) prototype.
The result?¶
- Eich delivers Mocha: A curly-braces language that looks a bit like Java, with prototype-based object-orientation inspired by the Self programming language, created in 10 days by someone expecting to implement a Scheme interpreter.
- In November 1995, Mocha, now renamed LiveScript, is included with the third beta release of Netscape Navigator 2.0.
- At the close of 1995, Java's popularity is skyrocketing from being included in Netscape Navigator and because both Netscape and Sun are happy about this, LiveScript is renamed again to JavaScript, because that will never cause confusion.
To summarize¶
- JavaScript has some superficial similarities to Java when it comes to syntax, but...
- JavaScript is not Java.
- JavaScript is not a subset of Java.
- JavaScript is not derived from Java (except in the most superficial sense).
- JavaScript does not work like Java.
- JavaScript does not require the Java Virtual Machine (but later JVM implementations do exist, as for most high-profile languages).
And conversely¶
- Java is not shorthand for JavaScript.
- Some of you have already fallen into this trap.
I heard that JavaScript is weird, is this why?¶
Well...¶
Microsoft invents their own scripting language¶
- Netscape Navigator is dominating the browser market in the mid 90s and are driving innovation, e.g. Java and JavaScript.
- Microsoft want to catch up with their own browser, Internet Explorer.
- By including IE for free with Windows 95, they set off the First Browser War (which they would end up winning de facto, if not de jure).
- Microsoft implements a new scripting language in Internet Explorer allowing web designers to build dynamic web pages.
- JScript: A curly-braces language that looks a bit like Java, with prototype-based object-orientation similar to what existed in the Self programming language, created in more than 10 days by a team of people who absolutely, definitely was not copying anything Netscape was doing and was not in any way encroaching on Sun's trademark, Java.
- (Because intellectual property is very important to Microsoft.)
European Computer Manufacturers Association (ECMA) get pulled in¶
- Netscape asks ECMA to be an independent mediator and come up with an open standard.
- ECMA needs an editor to head up the work on the new ECMA-262 standard, or ECMAScript. They ask Guy Steele. (Remember? The guy who invented Scheme? The language Netscape was supposed to use before corporate politics happened?)
- June, 1997: ECMAScript Edition 1
- June, 1998: ECMAScript Edition 2
- December, 1999: ECMAScript Edition 3
- March, 2000: The dot-com crash begins
Turmoil¶
- Netscape as a company does not survive the double punch of Microsoft business practices and the dot-com crash.
- However, its staff, seeing the writing on the wall, had set up the non-profit Mozilla Organization (later Mozilla Foundation) and Netscape Navigator today lives on in the DNA of Mozilla Firefox browser.
- Eich, now CTO of Mozilla, and others begin work on a new Edition 4 of ECMAScript to make it a more competent and complete programming language.
- Microsoft and Adobe find it "too radical" and refuse to co-operate (incidentally, it would also make the free and open standard JavaScript compete with their proprietary Silverlight and Flash softwares respectively).
- They form a sub-committee and start work on a "less radical" Edition 3.1 (which freezes development of new features and essentially only fixes bugs in Edition 3). They manage to win over Yahoo and Google.
- Squabbling goes on for 10 years until ECMAScript Edition 5 (essentially 3.1) is published in December 2009. Edition 4 is officially abandoned.
ES6 and normalization¶
- Squabbling continues until 2015 when a few of the more radical innovations from Edition 4 (a subset called ECMAScript Harmony) are finally included in ECMAScript Edition 6 (ES6), later renamed ECMAScript 2015.
- Modern JavaScript is often referred to collectively as ES6, since there is a very clear before and after this version.
- (By the way, with ES6, JavaScript got classes. You are allowed to facepalm.)
- Since then, a new standard with small incremental updates is released on a yearly basis.
- Edition 16, or ECMAScript 2025, is published in June, 2025.
To summarize again¶
- JavaScript is weird because it was never really planned out or thought through.
- The first version was just prototype never meant to be released in that state.
- Since then, development of the language has been driven, or inhibited, by corporate politics rather than practical considerations.
- Despite "recent" fixes to many issues, much weirdness is simply locked in since changing it would break the web as we know it.
</rant>¶
JavaScript features¶
- Interpreted
- Though techniques like JIT-compiling, hoisting, etc. give modern JS some features of compiled languages.
- Single-threaded
- Operations are executed one at a time in sequence with no native parallellization. Though this is less true now than for the first 20 years of JavaScript's existence.
- Multi-paradigm
- Object-oriented using prototyping, though classes are available since 2015.
- Functional, with first-class functions, anonymous functions, the option of constants, and higher-order built-ins like
map,reduce, andfilter, although few built-in functions are pure functions.
Where is JavaScript used¶
- On web pages as "client-side scripting" – this is what we'll be doing in this course
- On servers as "server-side scripting" – e.g. using Node.js, Deno and frameworks built on them
- Browser extensions – e.g. for Google Chrome
- Mobile app development – e.g. using ReactNative
- Desktop app development – e.g. using Electron
- Inside PDF documents to create interativity.
JavaScript is JavaScript, is JavaScript?¶
- The language and syntax is the same regardless of where we use it.
- What JavaScript operates on, i.e. what API the code is interacting with, is what varies.
Google Chrome Extension¶
// Create a simple text notification:
let notification = webkitNotifications.createNotification('48.png', // icon url - can be relative
'Hello!', // notification title
'Lorem ipsum...' // notification body text
);
JavaScript for PDFs - annotation¶
/* The getAnnot method returns an Annotation object, an object that holds all
data of the annotation. This method takes two parameters, nPage (page number)
and cName (the name of the annot). For example, */
let a = this.getAnnot({ nPage: 2, cName: "myAnnot" });
if ( a != null ) {
console.println("This annot has type " + a.type);
if ( (a.type != "FileAttachment") || (a.type != "Sound") )
console.println("The comment of this annot is " + a.contents);
}
Get div nodes from HTML DOM¶
let divs = document.getElementsByTagName('div');
for (let i = 0, div; div = divs[i]; i++) {
/* Process div in some way */
}
What can JavaScript do?
In fact, you can generate all HTML and CSS using only JavaScript and some frameworks appear to do just that.
JavaScript can be used to¶
- Manipulate the DOM, i.e.
- Change DOM structure
- Change the ID of DOM nodes
- Change the classes of DOM nodes
- Change contents of DOM nodes
- Manipulate the CSS
- Add inline CSS to the DOM
- Change the contents of the stylesheet
- Capture web browser events
- Changes to the web browser window (size, active/not active, URL etc)
- Changes originating from input devices: mouse movement, keyboard key presses, single and multitouch events
Creating an interactive interface using HTML, CSS and JavaScript¶
- Use HTML to represent initial elements and data.
- Use CSS to style and layout the content.
- Use JavaScript to
- Listen for specific web browser events on specific elements in the DOM.
- Change/Create elements in the DOM.
- (Access a back-end to retrieve persistent server-side data.)
JavaScript today¶
- Language features
- DOM access and traversal using the WebAPI
- Event handling
The JavaScript language¶
Assignment 2: Codecademy exercises¶
- Codecademy exercises to practice your JavaScript.
- Codecademy exercises should be completed individually by each group member.
- You will not learn JavaScript during this lecture, you will get an overview and refresher of your prerequisite knowledge of programming.
- You will also have to practice on your own to internalize anything covered here.
A note on JavaScript code style¶
- Use
camelCasefor variable and function names.- Start variable and function names with a lower case letter.
- Use meaningful names for variable and function names.
- Put spaces around operators, i.e.
1 + 2, not1+2. - Indentation is for readability only but should use spaces, not tabs, and be consistent (2 is recommended, 4 is accepted).
- I'll generally be using 4 for readability on my slides.
- Terminate statements with semicolon
;.
Types and variables¶
JavaScript is¶
- Dynamically typed
- I.e. like Python, though type annotations and static type checking somewhat like in Ada is an optional add-on (TypeScript).
- Lexically scoped
- Also called static scope. The body of a function is evaluated in the environment where the function is defined, not the environment where the function is called. This is the norm for most modern languages including Python and Ada (though in Ada you are usually forced to be so explicit about available variables that you might not notice).
- Garbage collected
- I.e. like Python or Java, no manual allocation or de-allocation of memory as in C, C++ or Ada.
Declaration and initalization of variables¶
- Variables are declared with the
letkeyword. - A variable does not have to be initialized (given an initial value) when declared.
- Differs from Python where declaration is implicit and happens the first time a variable is assigned a value.
- The first assignment to a variable initializes it (as long as it has been declared first).
- Referencing a variable declared with
letbefore initialization causes an error. - Declaration and initialization can be written on one line.
In [ ]:
let x;
x = "example";
let y = 5;
Hoisting¶
- In Python, referencing a variable before it is initialized generates an error.
- In JavaScript, variable declarations and function definitions are hoisted to the top of the scope before the code is run.
- However, variable initializations are not hoisted.
Constants¶
- The keyword
constcreates a constant, i.e. we are not allowed to change which value is referenced by the constant. - The referenced value itself is usually still mutable though.
- For example, if the value is an array:
In [ ]:
const veggies = ["Tomato", "Lettuce", "Pepper"];
veggies.push("Carrot"); // Adds a new element (Carrot) to veggies
console.log(veggies)
Variables declared with var¶
- The keyword
varcrates a variable with strange scope. - Before ES6, only
varexisted and it is still around in a lot of examples and legacy code so you need to know that it exists, but... - You should avoid
varin this course (or any new code since ES6), so I won't provide examples.
Levels of nothing¶
- Trying to access a variable that has not been declared will result in a
ReferenceError - When a variable is declared, but not initialized, it is
undefined:
In [ ]:
let value;
console.log(value)
- When a variable is declared and we want it to have a "non-value", we can set it to
null:
In [ ]:
let value = null;
console.log(value)
Static typing¶
- Type checking is done before runtime, usually during compilation for compiled languages or by a static code analyser (or linter) for interpreted languages.
- Datatype of the value a variable refers to is not allowed to change during runtime.
- Most often, type has to be explicitly declared when the variable is declared (though not always, e.g. Haskell is an exception where type is inferred but inconsistency, i.e. inferring different types for the same variable at different points in the code, cause type errors).
- Examples: C, Java
int i = 1; // Note how we explicitly declare that i is an int
i = "hello";
-> error
Dynamic typing¶
- Type checking is done during runtime.
- Datatype of the value a variable refers to can change during runtime.
- Type usually isn't declared, though sometimes type annotations can be added (like in Python or JavaScript) and even enforced (MyPy/PyRight and TypeScript respectively).
- Examples: Python, JavaScript
let i = 1; // Note how we only declare a variable, not its type
i = "hello";
-> no problem
Is JavaScript "weakly" typed?¶
- There is no strict definition of "weak" (or, sometimes, "loose") typing.
- Sometimes erroneously used to refer to dynamic typing.
- Can usually be interpreted as "This language has a type system I don't like."
- (Yes, I've been guilty of this many times.)
JavaScript's "weak" typing¶
- Fairly many situations with implicit type conversion that would lead to errors in other languages.
- A result of JavaScript originally being aimed at "web designers, not programmers".
- (sighing and rolling of eyes is allowed, nay encouraged, here)
- Example:
In [ ]:
let number_variable = 5;
let string_variable = "10";
let result = number_variable + string_variable ;
console.log(result);
Lexical scope¶
- Also called static scope (not to be confused with static type).
- "The body of a function is evaluated in the environment where the function is defined, not the environment where the function is called."
- I.e. variables are looked up where the code is written (lexically) not where the code is being run (usually called dynamic scope).
- Lexical scope is the norm today in most languages but can still trip you up.
In [ ]:
let name = "Johan";
function printName() {
console.log("The name is " + name);
}
function printFullName() {
let name = "Johan Falkenjack";
printName();
}
printFullName();
Scope chain¶
- JavaScript look up variables in the following order, equivalent to most languages with lexical scoping.
- Block Scope: Variables defined with
letandconstare limited to the block they are declared in, like loops or conditionals. - Nested Scope: Inner functions have access to variables in their parent functions.
- Local Scope: Variables defined inside a function or block, accessible only within that specific function or block.
- Global Scope: Variables defined outside any function or block, accessible anywhere in the program.
JavaScript in the browser
Connecting the script to the content¶
- Two ways of adding JavaScript to an HTML file
- Use the
<script>tag and write inline JavaScript
<script>
console.log("Hello World");
</script>
- Use the
<script>tag with the src attribute and reference a file with JavaScript code
<script src="helloworld.js"></script>
- The second approach is always preferable.
When is the JavaScript in the script tag run?¶
- The script is run when loaded.
- If the script depends on e.g. existing elements on the page, we need to load the script after those elements have been loaded.
- E.g.
- last inside the
<body>element. - when an approriate event happens (we’ll get to this later)
- last inside the
Use defer to run JavaScript only after DOM created¶
- Adding the
deferattribute to a script tag withsrcattribute will wait until the DOM has been constructed to run the linked JavaScript file
<script src="script.js" defer>
HTML + JS Examples¶
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Execution in HTML</title>
</head>
<body>
<!-- Inline JavaScript -->
<script>
console.log("Inline JavaScript executed");
</script>
<!-- External JavaScript file -->
<script src="external-script.js"></script>
...
Multiple source files
<!DOCTYPE html>
<html lang="en">
<head>
<title>Classic JavaScript Import Example</title>
</head>
<body>
<h1>Hello, Classic JavaScript Import!</h1>
<script src="greet.js"></script>
<script src="use-greet.js"></script>
</body>
</html>
//greet.js
function sayHello() {
console.log('Hello from classic JavaScript import!');
}
// use-greet.js
sayHello();
Modules
<!DOCTYPE html>
<html lang="en">
<head>
<title>JavaScript Modules Example</title>
</head>
<body>
<h1>Hello, JavaScript Modules!</h1>
<script type="module" src="use-module-example.js"></script>
</body>
</html>
// module-example.js
export function sayHello() {
console.log('Hello from the module!');
}
// use-module-example.js
import { sayHello } from './module-example.js';
sayHello();
JavaScript in the browser
JavaScript and the DOM¶
- More about the DOM
- What can we do with the DOM using JavaScript
- How can we use this to create interaction?
- What types of interaction - input/output - can we use in a web browser
- show/hide
- create/destroy
- move, position
- change shape, color
- click, drag, drop - elements on page and files from the computer
- type on keyboard
- images, movies, animations
Accessing the DOM tree¶
- Elements
- using querySelectors - use CSS selector syntax
- getElementsByTag
- getElementsByClass
- getElementById
- accessing an element’s relatives
- Text
- get an element’s text content
- using innerHTML
- Attributes
- get an element’s attribute nodes
- get an element’s specific attribute value
Accessing elements¶
The "old" way¶
- Both return a
HTMLCollectionobject.
document.getElementsByTagName("tagname")
document.getElementsByClassName("classname")
- Returns an
Elementobject.
document.getElementById("elementid")
- Can also be run on an element, e.g.
let mainMenu = document.getElementById("main-menu");
// get all li elements in #main-menu
let menuItems = mainMenu.getElementsByTag("li");
Newer query selectors¶
- We can use selectors that follow the CSS selector syntax.
- Using
querySelectorreturns anElementobject, if the selector matches multiple element, the first element matching the query is returned.
document.querySelector("#elementid")
- Meanwhile,
querySelectorAllreturns a staticNodeListobject
document.querySelectorAll(".classname")
Element relatives¶
// get the first element from a selector result
let myElement = document.querySelector(".box p");
// get an elements relatives
myElement.firstElementChild;
myElement.lastElementChild;
myElement.parentElement;
myElement.nextElementSibling;
myElement.previousElementSibling;
Accessing elements¶
// get a NodeList of elements using a selector query
myElements = document.querySelectorAll("div p");
// get a live HTMLCollection of elements of a specified type
myElements = document.getElementsByTagName("a");
// Elements in NodeLists and HTMLCollections can be accessed
// using an index.
Should I use getElements* or querySelectorAll?¶
- It will depend on use case.
document.querySelectorAll("p")returns a static, non-liveNodeListof all nodes (including text and attribute nodes).document.getElementsByTagName("p")returns a liveHTMLCollectiononly containing elements.- If a new paragraph is added to the DOM:
- the "live"
HTMLCollectionautomatically include the new element - the static
NodeListwill not, you will have to calldocument.querySelectorAll("p")again
- the "live"
- Note: Not all
NodeListsare static but the onesquerySelectorAllreturns are. - https://www.freecodecamp.org/news/dom-manipulation-htmlcollection-vs-nodelist/
Accessing element content¶
// get all HTML inside an element
allHTML = element.innerHTML;
// we can also change the inner HTML
element.innerHTML = "<img src='cat.jpg'>"
// just get the text content of an element
theText = element.textContent;
Accessing attributes¶
// array access to an element's attributes
theAttributes = element.attributes;
// get the value of an element's attribute
anAttribute = element.getAttribute("attributeName");
Editing the DOM tree
Change innerHTML and set an attribute value¶
// set inner HTML of an element
element.innerHTML = "new inner HTML";
// set the value of an element's attribute
element.setAttribute("attribute name", "attribute value");
Creating new nodes in the DOM tree
Create an element node¶
// create an h1 element
heading = document.createElement("h1");
// create a paragraph element
paragraph = document.createElement("p");
Create text nodes¶
- Any text inside a tag, e.g.
<p>text</p>is a text node. We can add multiple text nodes to a element.
// create heading text
headingText = document.createTextNode("Heading 1");
// create paragraph text
paragraphText = document.createTextNode("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, rem, adipisci, iste nisi vel quibusdam nulla tenetur repudiandae possimus maiores inventore doloremque asperiores aut omnis cum et harum provident suscipit!");
Add text nodes to elements¶
// create an h1 element
heading = document.createElement("h1");
// create a paragraph element
paragraph = document.createElement("p");
// create heading text
headingText = document.createTextNode("Heading 1");
// create paragraph text
paragraphText = document.createTextNode("Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam, rem, adipisci, iste nisi vel quibusdam nulla tenetur repudiandae possimus maiores inventore doloremque asperiores aut omnis cum et harum provident suscipit!");
// add text to heading and paragraph
heading.appendChild(headingText);
paragraph.appendChild(paragraphText);
Appending and inserting elements¶
// append paragraph to body, append always places an element last
body = document.getElementsByTagName("body")[0];
body.appendChild(paragraph);
// insert an element at a specific position
bodyNodes = body.childNodes;
body.insertBefore(bodyNodes[0], heading);
Changing the CSS for an element
Inline styles vs Stylesheet rules¶
- Inline styles are specified using the style attribute
- Example
<div class="box" style="border: 1px solid green;"></div>
- As mentioned; Do not use the style-attribute in your HTML files.
- Why? Specificity (see https://specifishity.com/)
- Overrides most CSS rules.
- Creates a tight coupling between content and style, i.e. makes it harder to specify style separately.
- However, if necessary, we can manipulate the style-attribute using JavaScript.
Set an element’s style using JavaScript¶
// grab the first heading
heading = document.getElementsByTagName("h1")[0]
// change the font-family property of the heading
// note that properties with a dash ('-') are camelCased
heading.style.fontFamily = "Times"
- While not as taboo as manually styling using the style-attribute in HTML, this approach should generally be avoided.
Manipulating style with class¶
// grab the first heading
heading = document.getElementsByTagName("h1")[0]
// set a class
heading.classList.add("maintitle");
// remove a class
heading.classList.remove("fancy");
- This is the preferred way of changing the style of an element using JavaScript.
- The JavaScript only changes the class, and any styling is written as rules in the CSS.
Functions in JavaScript¶
Functions¶
- function declaration: declare named function
- function expressions: create function objects
- regular function expressions
- arrow function expressions (ES6)
- Use of function expression as a value = anonymous function
- Use the
returnkeyword to return a value (except in arrow one-liners)
Function declaration¶
In [3]:
// function declaration, create a named function
function helloWorld() {
console.log("hello world");
}
helloWorld();
hello world
In [4]:
// function declaration with parameter
function greeting(name) {
console.log("hello " + name);
}
greeting("Charlie");
hello Charlie
Function expression¶
In [5]:
// defining an anonymous function, and keeping a reference to
// its function object
const f1 = function() {
console.log("Anonymous hello world");
}
f1();
Anonymous hello world
In [6]:
// function expression with a parameter
const f2 = function(somearg) {
console.log(somearg);
}
f2("Very secret message.")
Very secret message.
In [7]:
// referencing the function object of a named function
let hello = helloWorld;
hello();
hello world
Arrow functions¶
In [8]:
const f3 = () => {
console.log("This is also a function.");
}
f3();
This is also a function.
In [9]:
const f4 = (anotherarg) => {
console.log(anotherarg);
}
f4("Another secret message!")
Another secret message!
Arrow one-liners¶
In [10]:
let add1_oneliner = (value) => {return value + 1}
console.log(add1_oneliner(4))
5
- Curly braces can be omitted in which case return is implicit.
In [11]:
let add1_oneliner = (value) => value + 1
console.log(add1_oneliner(2))
3
- Parentheses can be omitted around single parameters.
In [12]:
let add1_oneliner = value => value+1
console.log(add1_oneliner(7))
8
Function declaration, function expression, or arrow function?¶
- Only functions created using function declaration are hoisted.
- Only expressions (though both traditional function expressions and arrow expressions) can create anonymous functions.
- Only expressions (again, both types) can be invoked directly, creating Immediately Invoked Function Expressions (IIFEs).
In [13]:
(() => {
console.log('This is printed despite the function not even being assigned a name or passed to a function.')
})()
This is printed despite the function not even being assigned a name or passed to a function.
User interaction - event handling
Elements have event handlers¶
- When an event is triggered in the context of an element, its event handlers are triggered
- Event examples
- when a mouse enters the area of an element
- when a mouse leaves the area of an element
- when the mouse is clicked on an element
- when a form field is given focus
Event handling¶
- Typical mouse interaction
onmouseoveronmouseoutonclick
- Typical form interaction
onfocusonbluronsubmit
Event handling in general¶
- Observer design pattern.
- A subject has a set of observers and methods to add and remove observers.
- The state of the subject changes by its
setState-method being called. - At the end of the
setStatemethod, the subjectsnotifyObservers-method is invoked. - The
notifyObservers-method informs each of the subject's observers that a state change has taken place by calling theirupdate-method. - Each observer's
update-method calls their subject'sgetState-method to get the subject's new state and change their behavior accordingly.
Observer pattern (simplified)¶
Event handling in web browsers¶
- Two possible ways
- Set the event handler property of element to the function to call when the event occurs
- These are the
onXproperties (onclick,onmousedown, etc.) - Just add "on" to the name of the event
- These are the
- Use
.addEventListener()and.removeEventListener()
Using event handler properties¶
- We can set an element's event property to
- a named function object or
- an anonymous function object
- Example of event handler properties
element.onkeydownelement.onkeyupelement.onmousedownelement.onmouseout
- Only one event handler can be specified
Using the event handler property¶
// using an anonymous function
element.onclick = function(event) {
alert("Hello World");
};
// using an arrow expression
element.onclick = (event) => {
alert("Hello World");
}
// using a function object
function hello(event) {
alert("Hello World!");
}
element.onclick = hello;
Adding an event handler as an event listener¶
- We can use the
element.addEventListener()method to add an event handler for a specific type of event - We specify the event type and the listener function, e.g.
element.addEventListener("keydown", keyhandler)
- Multiple listeners can be added to the same element.
Using .addEventListener()¶
// using an anonymous function
element.addEventListener('click', function(event) {
alert("Hello World");
});
// using an arrow expression
element.addEventListener('click',(event) => {
alert("Hello World");
});
// using a function object
function hello(event) {
alert("Hello World!");
}
element.addEventListener('click', hello);
Event objects¶
- Event handler functions recieve an
Eventobject that contains information about the event. - The kind of event decides what event type is sent
- All events have
Event.target: reference to origin of event
- MouseEvents have e.g.
MouseEvent.screenX,MouseEvent.screenY: X and Y coordinates of the mouse
- See https://developer.mozilla.org/en-US/docs/Web/API/Event#interfaces_based_on_event
DOM being loaded is an event too
<!DOCTYPE html>
<html lang="en">
<head>
<title>Delayed JavaScript Execution</title>
<script type="module" src="delay.js">
</script>
</head>
<body>
<p id="displayContentHere"></p>
</body>
</html>
document.addEventListener("DOMContentLoaded",
(event) => {
let contentParagraph = document.querySelector("#displayContentHere")
contentParagraph.textContent = "This paragraph got its content only after DOM was loaded even though the .js file was loaded without defer.";
})
Simple assignment¶
- Uses the
=operator like Python, Java, C, etc.- Requires that a variable be declared first but allows declaration and initialization on one line.
In [14]:
let x = 1;
console.log("Value of x:", x.toString())
Value of x: 1
Augmented assignment¶
- Combines an arithmetic operation with assignment, e.g.
a += b(addition assignment),a /= b(division assignment),a %= b(remainder assignment), etc.- Requires that a variable be initialized first.
- Essentially a shorthand for
a = a + b
In [15]:
let y = 10;
x += y;
console.log("Value of x:", x.toString())
Value of x: 11
Increment and decrement operators¶
- Increments (or decrements) by 1 and returns the value before or after the increment.
- Whether it returns the value before or after increment (or decrement) depends on whether the operator is prefixed or postfixed.
- If postfixed (
x++) it returns the value before the increment takes place. If prefixed (++x) it returns the incremented value.
- If postfixed (
In [16]:
let x = 5;
let before = x
let returned = x++
let after = x
console.log("Value before:", before.toString());
console.log("Value returned:", returned.toString());
console.log("Value after:", after.toString());
Value before: 5 Value returned: 5 Value after: 6
Datatypes¶
Datatypes¶
- Common datatypes
BooleanNumberStringArrayObjects
- Note: Lots more when we have access to the WebAPI
Numbers and operators¶
- All numbers in JavaScript are stored as floating point numbers in the
Numberdatatype.- Except integer values that are simply too large, which have their own type
BigInt(BigIntliterals are written as an integer followed byn, e.g.9007199254740991n).
- Except integer values that are simply too large, which have their own type
- Other than that, arithmetic works as in e.g. Python or Java.
In [17]:
let a = 3;
let b = 2.0;
console.log(a+b);
console.log(a-b);
console.log(a/b);
console.log(a*b);
5 1 1.5 6
JavaScript has two boolean values
falseandtrue- The following evaluate to
false, all other values evaluate totrue:false,null,undefined,0(zero),-0(minus zero),0n(BigIntzero),NaN"",'',``(empty string)
- Note that the empty
Arraydoes not evaluate tofalsethe way the equivalent value does in many other languages, e.g. Python.- This is because
Arrayis just a special case ofObjectand allObject-values evaluate totrue. - (This might be one of those this-was-created-in-10-days-gimme-a-break issues, or possibly a Scheme-is-actually-also-insane-and-interpret-the-empty-list-as-true issue. Or I'm just biased and this is actually fine.)
- This is because
Strings¶
- Like in Python, strings are immutable.
- I.e. any concatenation, replacement, slice, etc. creates a new string object.
In [18]:
let a = "Hello";
let b = "World!";
console.log(a + " " + b);
console.log(a, b);
Hello World! Hello World!
In [19]:
// length of string
console.log(a.length);
5
In [20]:
console.log(a.replace("l", "j"));
console.log(b.startsWith("Wo"));
Hejlo
true
Arrays¶
- An array in JavaScript is superficially similar to the list in Python.
- We can create a new, empty array in different ways, and we can use 0-based indexing to access elements.
In [22]:
let myArray1 = new Array();
let myArray2 = Array();
let myArray3 = [];
// we can fill an array when initializing it
let myArray4 = [1, 2, "hello"];
console.log(myArray4)
console.log(myArray4[0])
[ 1, 2, "hello" ] 1
- But if we start scratching the surface, JavaScript's
Arrayis actually quite different from Python's list.- E.g. we can set any position in an array, empty spots will be undefined
In [23]:
myArray4[5] = "what!";
console.log(myArray4)
[ 1, 2, "hello", <2 empty items>, "what!" ]
More on Array¶
In [24]:
let myArray = [1, 2, "hello", "world"]
console.log("Length of array:", myArray.length)
console.log("Pushing adds an element to end of array and returns the new length of the array:", myArray.push("yay"))
console.log("Popping removes and returns the last element of the array:", myArray.pop())
Length of array: 4 Pushing adds an element to end of array and returns the new length of the array: 5 Popping removes and returns the last element of the array: yay
Objects¶
- JavaScript is an object oriented language.
- However: based on prototypes, rather than classes
- Though ES6 introduced class declaration syntax, the dev community is split on when, or even whether, these should be used.
- Objects have properties.
- Properties are accessed using dot notation:
object.property - Properties can also be accessed using square bracket notation:
object["property name"]
- Objects can also have functions that can behave as methods.
- Functions in objects are called using dot notation:
object.function()
Object example¶
In [25]:
let image = {
filename: "cat1.jpg",
sayHello: function() {
console.log("Hello!");
}
}
console.log(image.filename);
image.sayHello();
cat1.jpg Hello!
Conditionals, comparisons and logical operators¶
Conditional statements¶
if (a == b) {
statement;
statement;
} else if (a == c) {
statement;
statement;
} else {
statement;
statement;
}
Comparison operators¶
- equal value (with type conversion):
== - equal value and datatype (no type conversion):
=== - less than:
< - less than or equal:
<= - greater than:
> - greater than or equal:
>= - different value:
!= - different value or different type:
!==
In [26]:
console.log(1=="1");
console.log(1==="1");
true false
Some weird (in)equalities in JavaScript¶
In [27]:
console.log([] == 0)
console.log(Boolean([]) == Boolean(0))
true false
In [28]:
console.log(null > 0)
console.log(null == 0)
console.log(null >= 0)
false false true
In [29]:
console.log(false == undefined)
console.log(false == null)
console.log(null == undefined)
false false true
In [30]:
console.log(0 == '')
console.log(0 == '0')
console.log('' == '0')
true true false
Conclusion: Use ===, not ==¶
Logical operators¶
- not:
! - and:
&& - or:
|| - We can do weird things with these as well:
In [31]:
console.log([] == ![])
true
Loops¶
Loops¶
whiledo ... whileforfor ... infor ... ofbreakandcontinue
The while loop - while this is true, do this¶
- Works like most other
while-loops you are likely to have experienced.
while (condition) {
//statement
//...
}
In [32]:
let x = 5;
while (x > 0) {
console.log("x: " + x--)
}
x: 5 x: 4 x: 3 x: 2 x: 1
The do while loop - do this, if this is true, loop¶
do {
//statements
//...
} while (condition);
- The loop body will always execute at least once. Very useful!
In [33]:
let x = 5;
do {
console.log("x: " + x--)
} while (false)
x: 5
C-style for loop - a while loop with bells and whistles¶
for (<loop variable declaration and initialization>; <while-like condition>; <compute next value>) {
// statements
// ...
}
In [34]:
for(let x = 5; x>0; x--) {
console.log("x: " + x);
}
x: 5 x: 4 x: 3 x: 2 x: 1
for ... in¶
- iterate over enumerable property in object
- "the keys" of an
Object - the indexes of and
Array
- "the keys" of an
for(property in object) {
// statements
}
In [35]:
let myArray = ["value 1", "value 2"]
for(let v in myArray) {
console.log("index: " + v);
}
index: 0 index: 1
for ... of¶
- iterate over iterable object
- "the values" of an
Object - the elements of an
Array
- "the values" of an
for(variable of object) {
// statements
}
In [36]:
let myArray = ["value 1", "value 2"]
for(let e of myArray) {
console.log("value: " + e);
}
value: value 1 value: value 2
As in e.g. Python, we can break and continue¶
break: abort current loopcontinue: skip the rest of the current iteration and move to the next iteration
FYI¶
- Other ways of iterating can be provided by the different datatypes, e.g.
.forEach()method inArrayandNodeListobjects- It's generally recommended to use these when possible.
- The classic
map,filter, andreducetrifecta is also available.