Internet Engineering
05
Introduction · JavaScript Basic · JavaScript & DOM & CSS · Event Handling · Web Applications · Summary
Fall 2026 ·
Amirkabir University of Technology
@1995parham
<script>
// JavaScript code goes here...
</script>
<script src="external.js" defer></script>
console.log('Hello World')
main functionfunction (and
also arrows)const, let,
or the legacy
varconst first, and
let only when you must reassignvar is what you will meet in old code —
the examples below use it to show why it was replaced
i = j = 0;
function f(){
let i;
i = j = 10;
}
f();
//i = 0, j = 10
var has a function scopelet has a block scope
let x = "abc";
x[0]='Z';
// does NOT work!!!
w = window;
function mutateArray(A) {
A[0] = 0;
}
let A = [1];
console.log(A); // [1]
mutateArray(A);
console.log(A); // [0]
function mutateNumber(n) {
n = 0;
}
let n = 1;
console.log(n); // 1
mutateNumber(n);
console.log(n); // 1
both arrays and numbers are passed by sharing. Whereas arrays are mutable, numbers are not.
function mutateArray(A) {
A = [0];
}
A = [1];
console.log(A); // [1]
mutateArray(A);
console.log(A); // [1]
Here we are no longer mutating the array; we are now binding the name A to a new array.
Objects can have properties and methods while primitive values can’t
const name = 'Darth Vader';
name.alignment = 'Lawful evil';
name.tellTheTruth = () => {
console.log('Luke, I am your father!');
};
console.log(name.alignment); // undefined
name.tellTheTruth(); // Uncaught TypeError: name.tellTheTruth is not a function
const name = new String('Darth Vader');
name.alignment = 'Lawful evil';
name.tellTheTruth = () => {
console.log('Luke, I am your father!');
};
console.log(name.alignment);
name.tellTheTruth();
var or not) scope is
either global or
function
function f() {
while(true) {
var x = 20;
}
// x = 20 here
}
let and
const can be used to define
block scope
function f() {
while(true) {
let x = 20;
}
// x is not accessible here
}
+ - * / % **+**= += -= *= /= %= ++ --== === != !== > >= < <=== "2" returns true, 2 === "2" returns false!= "2" returns false, 2 !== "2" returns true&& || !// /* */if-elseswitch-case? :whilefordo-whilebreak and continue
function name(input1, input2, ...){
...
return result;
}
retVal = name(input1, input2, ...);
function changeMe(value) {
value = 10;
}
function changePropertyInMe(value) {
value.x = 20;
}
point = { x: 10, y: 10, toString: () => console.log(`(${this.x}, ${this.y})`) };
console.log(point);
changeMe(point);
console.log(point);
changePropertyInMe(point);
console.log(point);
object.onclick = func;
square(5);
function square(y) {
return y * y;
}
let f = function (input1, input2, ...) {
...
return result;
}
let f = (input1, input2, ...) => {
...
return result;
}
let sq = x => x * x
let f = () => 0
let input = prompt("Please enter your name");
window.prompt returns stringi = Number.parseInt("10");f = Number.parseFloat("20.2");
let question = confirm("Do you want to continue?");
window.confirm returns a booleantruefalse
window.alert("We study 'Internet Engineering'");
document has a
write method — do
not use it
document.write("A sample message");
document.open(), which
erases the whole document — including
this slide deck. There is no Run button here for that reasontextContent or
insertAdjacentHTML insteadinnerHTML attribute
<span id="testbox">This is my innerHTML</span>
<script>
document.getElementById("testbox").innerHTML = "This is box";
</script>
This is my innerHTML
// a literal
let a = [1, 2, 3];
// the same thing with the Array constructor
let b = new Array(10, 20, 30);
// empty, then filled at arbitrary indices — the gaps are "holes"
let c = new Array();
c[10] = "HTML";
c[120] = "JS";
console.log(c.length); // 121
concat, shift, unshift,
sort, reverse, indexOf, ...
let friends = ["Saman", "Sepehr", "Hessam"];
friends.length // 3
friends.push("Ali") // 4
friends.concat("Ali") // ["Saman", "Sepehr", "Hessam", "Ali", "Ali"]
let last = friends.pop() // "Ali"
last // "Ali"
friends.map(i => i.toUpperCase()) // ["SAMAN", "SEPEHR", "HESSAM"]
friends.filter(i => i.startsWith("S")) // ["Saman", "Sepehr"]
let num = [1, 2, 3, 4, 5, 6, 7, 8, 9];
num.reduce((sum, i) => sum + i, 0) // 45
for (let friend of friends) {
console.log(friend)
}
// From a length
let uint8 = new Uint8Array(2);
uint8[0] = 42;
console.log(uint8[0]); // 42
console.log(uint8.length); // 2
console.log(uint8.BYTES_PER_ELEMENT); // 1
uint8[2] = 1;
console.log(uint8[2]); // undefined
console.log(uint8.length) // 2
abs,
sin,
asin,
ceil,
floor,
log,
exp,
pow,
random, ...
let num = 1.1;
num.toExponential() // '1.1e0'
num.toFixed() // '1'
let d = new Date();
d.toString(); // "Thu Nov 05 2020 09:50:38 GMT+0330 (Iran Standard Time)"
d.set/get FullYear, Month,
Date, Hours, Minutes,
Seconds
let book = {
name: "OOP in JS",
price: 100,
publish: 2020,
getPrice: function(){
return this.price;
}
};
book.setPrice = function (x){this.price=x;};
book.setPrice(1000);
window.alert("name is "+ book.name +", price is "+ book.getPrice());
Object object and
new
let book = new Object();
book.name = "OOP in JS";
book.price = 100;
book.publish = 2020;
book.getPrice = function() { return this.price; };
book.setPrice = function(x) { this.price=x; };
book.setPrice(1000);
window.alert("name is "+ book.name +", price is "+ book.getPrice());
let book = {
name: "OOP in JS",
_price: 0,
get price(){
return this._price + "$";
},
set price(val){
if (val < 0)
window.alert("Invalid price");
this._price = val;
}
};
book.price = 1000;
window.alert("name is "+ book.name +", price is "+ book.price);
book.price = -100;
book._price = -100;
window.alert("name is "+ book.name +", price is "+ book.price);
Object.create(): creates a new object,
using an existing object as the prototype of the newly created object.
// Person is our portotype
let Person = {
_name: "",
_family: "",
get name() {
return this._name;
},
get family() {
return this._family;
},
set name(name) {
this._name = name;
},
set family(family) {
this._family = family;
},
};
// p1 is an instance based on Person prototype
let p1 = Object.create(Person);
p1.name = "Parham";
p1.family = "Alvani";
console.log(p1.name, p1.family);

function Person(first, last, age, gender, interests) {
// property and method definitions
}
let person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']);
Person.prototype.farewell = function() {
alert(this.name.first + ' has left the building. Bye for now!');
};
prototype property of the functionclass, which is a
special functionextends,
super, ...newdelete.thisnew Foo(...) do?Foo.prototypeFoo is called
with the specified arguments, and with
this bound to the newly created object.classfunction# (ES2022, supported everywhere)
class Student {
name; // public field
#id; // private field — not reachable from outside
constructor(name, id) {
this.name = name;
this.#id = id;
}
#check() { // private method
return this.#id.length === 7;
}
get id() {
return this.#check() ? this.#id : "invalid";
}
}
const s = new Student("Parham", "9231058");
s.#id; // SyntaxError: Private field '#id' must be declared in an enclosing class
protected in JavaScriptstaticconstructorsuper
function Student(name, id){
window.alert("I am going to create a new student");
this.name = name;
this.id = id;
this.toString = function(){
return `${this.name}: ${this.id}`;
}
}
let st1 = new Student("Parham Alvani", "9231058");
console.log(st1);
class Student {
constructor(name, id){
window.alert("I am going to create a new student");
this.name = name;
this.id = id;
}
toString() {
return `${this.name}: ${this.id}`;
}
}
let st1 = new Student("Parham Alvani", "9231058");
console.log(st1);
class Bachelor extends Student {
constructor(name, id){
super(name, id);
this.average = function() {
return 20;
}
}
isPass(){
return 'Pass';
}
static betterThan(a, b){
return a.average() >= b.average();
}
}
bc1 = new Bachelor("Parham Alvani", "9231058");
console.log(bc1.average());
bc2 = new Bachelor("Sepehr Sabour", "9231011");
console.log(bc2.average());
console.log(Bachelor.betterThan(bc1, bc2));
"use strict" directive was new in
ECMAScript version 5."use strict"; to the beginning of a
script or a
function.
"use strict";
myFunction();
function myFunction() {
y = 3.14; // This will also cause an error because y is not declared
}
JavaScript has a concurrency model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.
Function calls form a stack of frames.
Objects are allocated in a heap which is just a name to denote a large (mostly unstructured) region of memory.
A JavaScript runtime uses a message queue, which is a list of messages to be processed. Each message has an associated function which gets called in order to handle the message.
while (queue.waitForMessage()) {
queue.processNextMessage()
}
(function () {
let el = document.getElementById("event-loop");
el.innerHTML += "this is the start<br />";
setTimeout(function cb() {
el.innerHTML += "Callback 1: this is a msg from call back<br />";
}); // has a default time value of 0
el.innerHTML += "this is just a message <br />";
setTimeout(function cb1() {
el.innerHTML += "Callback 2: this is a msg from call back<br />";
}, 0);
el.innerHTML += "this is the end<br />";
})();
Promise is in one of these states:.then() method takes up to two
arguments; the first argument is a callback function for the
resolved case of the promise, and the second
argument is a callback function for the
rejected case.
// timeout is 300 millisecond
const timeout = 300;
function longCalculation(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`resolved-${id}`);
}, timeout);
});
}
longCalculation(1)
.then((result) => {
console.log(`1st promise: ${result}`);
return longCalculation(2);
})
.then((result) => {
console.log(`2nd promise: ${result}`);
return longCalculation(3);
})
.then((result) => {
console.log(`3rd promise: ${result}`);
return;
});
then reads backwards once there
are more than two stepsasync and
await let you write the
same promises as if they were sequential codeawait pauses only the function it is in,
never the browser
async function run() {
const first = await longCalculation(1);
console.log(`1st promise: ${first}`);
const second = await longCalculation(2);
console.log(`2nd promise: ${second}`);
const third = await longCalculation(3);
console.log(`3rd promise: ${third}`);
}
async function
always returns a promisetry/catch works
async function load() {
try {
const response = await fetch("https://swapi.dev/api/people/1/");
if (!response.ok) {
throw new Error(`unexpected status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error(error);
}
}
awaits in a row run
one after the other
// 600ms: the second starts only after the first resolves
const a = await longCalculation(1);
const b = await longCalculation(2);
// 300ms: both are already running
const [c, d] = await Promise.all([longCalculation(3), longCalculation(4)]);
undefined throws, so
deep access needs a guard at every level?. stops and evaluates to
undefined instead of throwing
// before
const city = user && user.address && user.address.city;
// after
const city = user?.address?.city;
|| replaces every falsy value,
which eats 0 and the empty string?? only replaces null and
undefined
const count = 0;
count || 10; // 10, almost certainly a bug
count ?? 10; // 0, the value we actually have
// calculation.js
export const timeout = 300;
export function longCalculation(id) {
return new Promise((resolve) =>
setTimeout(() => resolve(`resolved-${id}`), timeout),
);
}
// main.js
import { longCalculation, timeout } from "./calculation.js";
console.log(await longCalculation(1), timeout);
type="module"await works at the top level
<script type="module" src="main.js"></script>
window is the
browser window
<form name="nametest">
<input name="output" type="text" value="Default Text">
</form>
document.nametest.output.value='New Value';
element.getElementById("id")element.getElementsByClassName("classname")element.getElementsByTagName("tagname")element.getElementsByName("name")element.querySelector("CSS Selector")HTMLCollection and
NodeList are
not arrays: no map, no
filter. Convert first
const items = Array.from(document.getElementsByClassName("testbox"));
items.map((el) => el.textContent);
// querySelectorAll returns a NodeList, which does have forEach
document.querySelectorAll(".testbox").forEach((el) => console.log(el));
<div id="box1">
<div class="testbox">
document.getElementById("box1").innerHTML="I am the new message"
let da = document.getElementsByClassName("testbox");
da[0].innerHTML="I am another new message";
innerHTMLclassName
document.getElementById("My_Element").className += " My_Class";
childrenparentNodestylevaluestyle propertystylebackground-colorbackgroundColorobject.style.PropertyNameInDOM
let color;
index = prompt("Enter 1 for blue, 2 for red, 3 for green");
switch(parseInt(index)) {
case 1:
color = "blue"; break;
case 2:
color = "red"; break;
case 3:
color = "green"; break;
default:
color = "black"; break;
}
document.getElementById("colorBox").style.backgroundColor = color;
onclick is called when object (html element) is
clicked
<tag onclick="// JavaScript code, or a call to function()">
object.onclick=function
| Event | Occurs when... |
|---|---|
| onabort | a user aborts page loading |
| onblur | a user leaves an object |
| onchange | a user changes the value of an object |
| onclick | a user clicks on an object |
| ondblclick | a user double-clicks on an object |
| onfocus | a user makes an object active |
| onkeydown | a keyboard key is on its way down |
| onkeypress | a keyboard key is pressed |
| onkeyup | a keyboard key is released |
| onload | a page is finished loading. |
| onmousedown | a user presses a mouse-button |
| onmousemove | a cursor moves on an object |
| onmouseover | a cursor moves over an object |
| onmouseout | a cursor moves off an object |
| onmouseup | a user releases a mouse-button |
| onreset | a user resets a form |
| onselect | a user selects content on a page |
| onsubmit | a user submits a form |
| onunload | a user closes a page |
<input
id="clickbtn"
type="button"
value="click"
onmouseover="document.getElementById('msg').innerHTML='Click Here'"
onmouseout="document.getElementById('msg').innerHTML='Outside! Clicks are ignored'"
onmousedown="mouseDown()"
/>
<div id="msg" style="width: 50%"></div>
<script type="text/javascript">
let counter = 0;
function mouseDown() {
counter++;
document.getElementById("msg").innerHTML = "A new click";
}
function mouseUp() {
window.alert("Total # of clicks = " + counter);
}
document.getElementById("clickbtn").onmouseup = mouseUp;
</script>
function setBgColor(color) {
document.getElementById('change-my-color').style.backgroundColor = color;
}
<button onclick="setBgColor('red')">Red</button>
<button onclick="setBgColor('green')">Green</button>
color: <input type="text" id="color" />
<button id="set">set</button>
function setBgColor2() {
document.getElementById('change-my-color-2').style.backgroundColor =
document.getElementById("color").value;
}
document.getElementById("set").onclick = setBgColor2;
color:
this only when the handler
is registered in JS
function setBgColor3() {
window.alert("this = " + this);
this.style.backgroundColor = this.innerHTML.toLowerCase();
}
document.getElementById("r").onclick = setBgColor3;
document.getElementById("b").onclick = setBgColor3;
<button id="r">Red</button>
<button id="b">Blue</button>
<button onclick="this.style.backgroundColor =
this.innerHTML;">Green</button>
<!-- how we can fix this? -->
<button onclick="setBgColor3();">Black</button>
<button onclick="setBgColor3.bind(this)();">Black</button>
object.onclick = function
object.addEventListener(eventName, function)
object.removeEventListener(eventName, function)
<button onclick="AddEventHandler();">
Add a 'click' event listener to the blue button
</button>
<button onclick="RemoveEventHandler();">Remove the event listener</button>
<button id="blueButton" style="background-color: #0077ff">Big Blue Button</button>
<script type="text/javascript">
function blueClick1() {
alert("You have clicked on me!!!");
}
function blueClick2() {
alert("Yahoooo!!!!");
}
function AddEventHandler() {
let blueButton = document.getElementById("blueButton");
blueButton.addEventListener("click", blueClick1);
blueButton.addEventListener("click", blueClick2);
}
function RemoveEventHandler() {
let blueButton = document.getElementById("blueButton");
blueButton.removeEventListener("click", blueClick1);
}
</script>
event objectstopPropagation method on the event
object to prevent handlers further up from receiving the event.
<div id="parent" style="border: solid">
I am parent <br />
<button id="click-btn-1">click me</button>
</div>
// counter have been declared before
counter = 0;
function childHandler(event) {
window.alert("child handler");
counter++;
// add message to the event
event.message = `You have clicked me ${counter} times`;
}
document
.getElementById("click-btn-1")
.addEventListener("click", childHandler);
document.getElementById("parent").addEventListener("click", (event) => {
window.alert(
`child message that is added into event: ${
event.message ?? "use clickme button"
}`
);
});
<button onclick="alert('Hello world!')">
The JavaScript code in the attribute is passed the Event object via the
event parameter.
// Assuming myButton is a button element
myButton.onclick = function(event){alert('Hello world')}
The function can be defined to take an
event parameter.
Event.target A reference to the target to
which the event was originally dispatched.Event.type The name of the event.
Case-sensitive —
addEventListener("Click", …) never fires.
event.target vs.
this
document.createElement(tagName)
element.getAttribute(name)
element.setAttribute(name, value)
parent.appendChild(child)
parent.insertBefore(newChild, existingChild)
parent.removeChild(child)
parent.replaceChild(newChild, oldChild)
let id = 0;
function addNewP() {
id++;
let parent = document.getElementById("main");
let newp = document.createElement("p");
newp.id = "newp" + id;
newp.innerHTML = "I am new paragraph";
parent.appendChild(newp);
}
let replace = 0;
function replaceNewP() {
replace++;
if (replace <= id) {
let parent = document.getElementById("main");
let newp = document.getElementById("newp" + replace);
let newer = document.createElement("span");
newer.style.borderStyle = "solid";
newer.innerHTML = "I replace the new paragraph";
parent.replaceChild(newer, newp);
} else {
replace = id;
}
}
text,
password, and
textarea.value of
the corresponding objectselectoption is given by
SelectObject.valuecheckbox and
radio.checked == true is selected.valueOutput will be here:
function upperCaseArea(textareaID, outputID) {
return () => {
let textareaObject = document.getElementById(textareaID);
let content = textareaObject.value.toUpperCase();
let outputObject = document.getElementById(outputID);
// textContent, not innerHTML: the input came from the user and must
// never be parsed as markup. See the Web Security lecture.
outputObject.textContent = content;
};
}
document.getElementById("btnID").onclick = upperCaseArea("txtID", "outID");
function findOS(inputCheckBoxs, Outputdiv) {
let boxes = document.getElementsByName(inputCheckBoxs);
let outputMessage = "Ok, you are master in ";
for (let i = 0; i < boxes.length; i++) {
if (boxes[i].checked) outputMessage += " " + boxes[i].value + ", ";
}
document.getElementById(Outputdiv).innerHTML = outputMessage;
}
reg_expr = /expression/;
// The test() method executes a search for a match between a regular expression and a specified string.
// Returns true or false.
reg_expr.test(string)
// The match method retrieves the matches when matching a string against a regular expression.
string.match(reg_expr)
c* | ≥ 0 of c | c+ | ≥ 1 of c |
c? | 0 or 1 of c | c{x} | x times of c |
. | A char (no new line) | c1|c2 | c1 or c2 |
[] | Any combination of given characters | [^] | Any string without the given characters |
\d | A digit | \D | Every thing except digits |
^c | Beginning match | c$ | End match |
// anchored: the whole string must match
let anchored = /^ab*c+d{3}z$/;
// "acz": False
// "abbccdddz": True
// "ffabbccdddz": False
// unanchored: a match anywhere in the string is enough
let anywhere = /ab*c+d{3}z/;
// "abbccdddz": True
// "ffabbccdddz": True
// "ffabbccdddzggg": True
// To match Date format:
let dateRegex = /^\d{4}\/\d{1,2}\/\d{1,2}$/
function checkpassword(event) {
const p1 = document.passwordform.password.value;
const p2 = document.passwordform.repassword.value;
if (p1.length < 6) {
alert("Password is too short, re-enter");
event.preventDefault();
} else if (p1 !== p2) {
alert("The two passwords do not match");
event.preventDefault();
}
// otherwise the browser goes ahead and submits
}
document.getElementsByName("passwordform")[0].onsubmit = checkpassword;
Event.preventDefaultThe Event interface's preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.
Toggling a checkbox is the default action of clicking on a checkbox.
document.querySelector("#id-checkbox").addEventListener("click", function(event) {
document.getElementById("output-box").innerHTML += "Sorry! <code>preventDefault()</code> won't let you check this!<br>";
event.preventDefault();
});
<p>Please click on the checkbox control.</p>
<form>
<label for="id-checkbox">Checkbox:</label>
<input type="checkbox" id="id-checkbox"/>
</form>
<div id="output-box"></div>
Please click on the checkbox control.
document object is created by browser for
each HTML page (document) that is viewedanchors, forms, images,
links, scripts | Array of different types of HTML elements |
body | The object corresponding to <body> |
dir | Document direction |
title | Title of the document |
cookie, location, domain, ... | Information about HTTP |
من یک متن فارسی هستم
window objects provide useful
properties and methods to work with browser windowwindow object is created for each window/tab that
appears on the screendocument | This is the document object (that we have seen) |
history | Provides information on the browser history of the current window; method to go forward and backward in the history |
*Height *Width | Height & width of window or screen |
location | URL of the window |
screen.height: | screen.width: | ||
screen.availHeight: | screen.availWidth: | ||
outerHeight: | outerWidth: | ||
innerHeight: | innerWidth: |
let tooSmall = 0;
let content;
window.onresize = function () {
console.log(`new window ${window.innerWidth} x ${window.innerHeight}`);
console.log(`small: ${tooSmall}`);
if (
tooSmall == 0 &&
(window.innerHeight < 250 || window.innerWidth < 500)
) {
tooSmall = 1;
let el = document.getElementsByName("window-properties")[0];
if (el != null) {
content = el.innerHTML;
el.innerHTML = "";
msg = document.createElement("h1");
msg.innerHTML = "The window is too small, please resize!!!";
el.appendChild(msg);
}
}
if (
tooSmall == 1 &&
window.innerHeight >= 250 &&
window.innerWidth >= 500
) {
tooSmall = 0;
document.getElementsByName(
"window-properties"
)[0].innerHTML = content;
}
};
forward(), back() | One time forward or back in history |
stop(), close() | Stop page loading or close it |
open() | Create new window |
Alert "Hello" every 3 seconds (3000 milliseconds)
let hello = setInterval(() => alert("Hello"), 3000);
clearInterval(hello)
Alert "Hello" after 3 seconds (3000 milliseconds)
let hello = setTimeout(() => alert("Hello"), 3000);
clearTimeout(hello)
navigatorappCodeName: | |
appName: | |
appVersion: | |
language: | |
platform: | |
userAgent: |
httpOnly attributedocument.cookie as a
stringdocument.cookiedocument.cookiewindow.localStorage object stores the
data with no expiration date.
// store
localStorage.setItem("lastname", "Smith");
// retrieve
document.getElementById("result").innerHTML = localStorage.getItem("lastname");
// remove
localStorage.removeItem("lastname");
window.sessionStorage object is equal
to the localStorage object, except that it stores the data for only one
session.Fetch API provides a JavaScript
interface for accessing and manipulating parts of the
HTTP pipeline, such as requests and
responses.fetch() method
that provides an easy, logical way to fetch resources
asynchronously
across the network.fetch() method takes one mandatory
argument, the path to the resource you want to fetch.Promise that resolves to the
Response to that request, whether it is
successful or not.
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
fetch('flowers.jpg')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.blob();
})
.then(myBlob => {
myImage.src = URL.createObjectURL(myBlob);
})
.catch(error => {
console.error('There has been a problem with your fetch operation:', error);
});
function swapiExec() {
fetch("https://swapi.dev/api/people/1/")
.then((resp) => resp.json())
.then(
(data) =>
(document.getElementById(
"swapi-result"
).textContent = JSON.stringify(data))
);
}
Waiting...
function wikiSWLogo() {
fetch(
"https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/Star_Wars_Logo.svg/330px-Star_Wars_Logo.svg.png"
)
.then((resp) => resp.blob())
.then((content) => {
let img = document.createElement("img");
img.src = URL.createObjectURL(content);
document
.querySelector("section.present > section.present")
.appendChild(img);
});
}
function fetchWithErr(url) {
fetch(url)
.then((response) => {
if (!response.ok) {
throw new Error(
"Network response was not ok, " + response.status
);
}
return response.text();
})
.then((content) => {
document.getElementById(
"errMessage"
).innerHTML += `Success: <code class="hl-orange">${content}</code><br />`;
})
.catch((error) => {
document.getElementById(
"errMessage"
).innerHTML += `There has been a problem with your fetch operation: <code class="hl-red">${error}</code> <br />`;
});
}
document.createElement(), parent.appendChild()regex.test(input.value())document.property corresponding to HTTP headerswindow.*.height/widthwindow.setInterval()window.locationnavigator.userAgent/appVersion/...document.cookieconsole.log()/info()/warn()/error()this refers to whatever the function was called
on, not to where it was written — inside a plain function call
it is undefined in strict mode and modules, and the
window object otherwise
