Index

Table of contents

Javascript

dialogs

alert('hello');
var bool = confirm('are you sure? ok:cancel');
var string = prompt('what are you thinking about?');

logging

clear the console
console.clear();
log a message
console.log(new Date());

basics

strict

enable strict checks (catches possible problems in the code)
"use strict";

comments

single line comment
// this is a comment
multiline comment
/* this is a comment */

variables

block scoped variable (let)
for(let i=0; i<10; i++) { ... }
function scoped variable (var)
function myfunc() {
	var i=0;
}
global variable
i=0;

type checks

get the type of a variable
typeof [variable]
check the type of a variable
if(d instanceof Date) {
	document.write("date");
} else {
	document.write("not a date");
}

null / undefined

check if variable exists
if(typeof selenium === 'undefined') {
if(typeof selenium !== 'undefined') {
check for null or undefined
if(v == null) {
get the first non-null (non-undefined) value
let val = a ?? b ?? c;
a ??= b;
null-safe property selector
let prop = document?.foo?.bar?.baz;
undefine an object property
var isDeleted = delete obj.prop;
for variables use
[variable] = null;
check whether or not a property exists
if("prop" in obj) {
	console.log('exists!');
} else {
	console.log('missing!');
}
evaluate expression, but return undefined
void [expr];
<a href="javascript:void window.open()">popup</a>

data types

boolean

literals
true
false
convert variable to boolean
Boolean(x);
operators
a && b    logical and (short circuit)
a || b    logical or (short circuit)
! a       logical not
a &&= b   a = a && b
a ||= b   a = a || b
meaning of Boolean(x) for different data types
null → false
undefined → false
number → 0 = false, NaN = false, else true
string → "" = false, else true
object → null = false, not null = true

numbers

number literal
a = 1
b = 0.1
c = .01
d = 1e-3
e = 1E-4
operators
a + b
a - b
a * b
a / b
a ** b     # power
global functions
isNaN(number);
isFinite(number);     # not Nan, not ∞ and not -∞
convert to string with all significant digits
String(number);
number.toString();
"" + number
convert to string with custom format
number.toFixed(decimalDigits);                    # no exponent
number.toExponentional(decimalsBeforeExponent);   # exponent always
number.toPrecision(significantDigits);            # uses exponent only if necessary

strings

common escape sequences
\t      tab
\n      newline
\r      carriage return
\'      quote
\"      double quote
\\      backslash
\xXX    latin-1 character
\uXXXX  unicode character
properties
length
operators
var concat = "head" + ":" + "tail"
var char = str[i];
common functions
trim()
trimStart()
trimEnd()
padStart(minLength, padChar)
padEnd(minLength, padChar)
replaceAll(query, replacement)
startsWith(query);
substring(start, lastExclusive)
charAt(index)
indexOf(subtring)
toUpperCase()
toLowerCase()
contains substring
string.includes(substring)
regex split
str.split([regex], [limit])
convert string to number
Number(str);
str - 0;
parseInt(str);
parseInt(str, base);
parseFloat(str);

arrays

initialize empty array
var a = [];
var a = Array();
initialize array with values
var a = [ 1, 2, 3 ];
var a = [ 1, , 3 ];        # middle value is undefined
var a = Array(12);         # 12 undefined elements
var a = Array(1, 2, 3);    # 12 undefined elements
get the array length
myarray.length
testing if a variable is an array
var bool = Array.isArray(a);
iterating elements
myarray.forEach(myFunction);
add an element
a.push(element);          # in place at end of array
a.unshift(element);       # in place at start of array
a[index] = element;       # in place at specified index
a[a.length] = element;    # in place at end of array
a.concat(element)         # clone array and add element
removing an element
a.shift()     # from start
a.pop()       # from end
truncate array
a.length = [new length]
find an element in an array
var bool = a.includes(b);
var index = a.indexOf(b);
var index = a.lastIndexOf(b);
clone and extract a slice
myarray.slice(3);      # from this index
myarray.slice(3,5);    # from index (inclusive) up to index (exclusive)
extract a slice in place
a.splice(3);                # from this index
a.splice(3,5);              # from index (inclusive) up to index (exclusive)
a.splice(3,5,e1,e2,...);    # insert new elements in place of extracted slice
clone and join 2 arrays
a.concat(b)
flatten multidimensional array
a.flat();
reversing an array
myarray.reverse()
sorting an array
a.sort();
a.sort(myComparatorFunction);
functional methods
a.every([function]);   // true iff all are true
a.some([function]);    // true iff any are true

a.filter([function]);
a.flatMap([function]);
a.map([function]);
a.reduce(function(a,b) {return a+b});
array to string
a.toSring()    # comma separated
a.join('#')    # custom separator string

functions

defining a function
function hello(x)         { alert('hello ' + x); }
var hello = function (x)  { alert('hello ' + x); }
var hello = function h(x) { alert('hello ' + x); }
var hello = Function ("x", "alert('hello ' + x);");
defining a lambda
var mapped = [3,2,1].map(i => 2*i);
parameters
function myFunction(p1, p2) {
	return p1 * p2;
}
optional parameter
function sum(p1, p2) {
	var opt = p2 || 1;
	return p1 + opt;
}
default parameters
function sum(p1, p2=1) {
	return p1 + p2;
}
varargs
function sum() {
	var total = 0;
	for(var i=0; i<arguments.length; i++) {
		total += arguments[i];
	}
	return total;
}
validate argument type
function takesNumber(n) {
	if (!(n instanceof number)) {
		throw new Error('not a number: ' + n);
	}
}
validate argument count
function argumentCount(a,b) {
	if (arguments.length != arguments.callee.length) {
		throw new Error('invalid argument count');
	}
}

reflection

use reflection to examine current function
arguments.callee           reference to this function (can be invoked)
arguments.callee.length    number of arguments declared
arguments.length           number of arguments invoked

control flow

if statment

if(expression)
	statement;
else if (expression)
	statement;
else if (expression)
	statement;
else
	statement;

ternary operator

var result = flag ? yesValue : noValue;

while

normal while loop
while (expression)
	statement;
do while loop
do
	statement;
while(expression);

for loop

iterate array
for(i=0; i<parent.length; i++) {
	console.log(parent[i]);
}
iterate array with for each
for (x of myarray) {
  console.log(x);
}
alternative syntax
myarray.forEach(function(x) {
  console.log(x);
})
iterate properties of object
for (x in obj) {
  text += obj[x];
}

switch statement

switch(value) {
	case a:
		break;
	case b:
		break;
	default:
		return;
}

labels

continue and break with labels
outer:
	for(var i=0; i<100; i++)
		inner:
			while(true) {
				if(i%2 == 0) {
					document.write("even ");
					continue outer;
				}
				if(i%2 == 1) {
					document.write("odd");
					break outer;
				}
			}

exception handling

try catch
try {
	statement
} catch(e) {
	statement
} finally {
	statement
}
the argument to catch is optional
try {
	statement
} catch() {
	statement
}

math

constants

Math.E        # base of natural logarithm
Math.PI
Math.SQRT2    # √2

functions

random number
Math.random();
round numbers
Math.floor(number)
Math.round(number)
Math.ceil(number)
square root
Math.sqrt(number);
min max
Math.min(a,b);
Math.max(a,b);
absolute
Math.abs(x);
trigionomotry
Math.sin(x);
Math.cos(x);
Math.tan(x);
Math.asin(x);
Math.acos(x);
Math.atan(x);
exponents
Math.pow(x, y) # x^y
Math.exp(x)    # e^x
math.log(x)    # log₁₀(x)

Dates

constructor
var now = new Date();
var stamp = new Date(millis);
var specific = new Date(year, month, day);
var formatted = new Date(string);
methods
d.getFullYear();
d.getMonth();
d.getDay();
d.getHours();
d.getMinutes();
d.getSeconds();
d.getMilliseconds();
d.toISOString();

d.setFullYear(value);
d.setMonth(value);
d.setDay(value);
d.setHours(value);
d.setMinutes(value);
d.setSeconds(value);
d.setMilliseconds(value);

Date.parse(string);
get timestamp
Date.now();
new Date().getTime();

concurrency

timers

invoke with a delay
setTimeout(function() { alert('foo'); }, [millis]);
setTimeout(function(arg1) { alert(arg1); }, [millis], arg1);
recurring timer event
setInterval(myfunction, 100);

promises

promise hello world
Promise.resolve("hello world").then(value => console.log(value));
create a Promise that returns a value
Promise.resolve(someValue);
create a Promise that returns an error
Promise.reject(new Error("some awful error"));
chain an additional function to a promise
p.then(nextfunc);
error handling
p.catch(error => console.log('caught:' + error));
invoke code after promise is settled
p.finally(() => console.log('promise complete'));
promise with function
var p = new Promise(function(resolve, reject) {
	// calls Promise.resolve(new Date()) with a 1 second delay
    setTimeout(resolve, 1000, new Date());
}).then(function(result) {
	console.log(result.getSeconds() + ' => ' + new Date().getSeconds());
});
simplified syntax for invoking promises (async & wait)
function funcThatReturnsPromise() {
  return Promise.resolve("log value in invokePromise");
}
async function invokePromise() {
  var funcResult = await funcThatReturnsPromise();
  console.log(funcResult);
}
invokePromise();

promise aggregator functions

trigger then, when all promises complete successfully
Promise.all();
wait for all promises to either pass or fail; return an array containing their results
Promise.allSettled();
trigger then, when one promise completes successfully
Promise.any();
trigger then (catch), when one promise completes successfully (unsuccessfully)
Promise.race();

object orientation

classes

class hello world
class Hello {
	sayHello() {
		console.log('hello');
	}
}
new Hello().sayHello();
attributes
class Truck {
	name = "John";
}
constructor
class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
console.log(new Rectangle(100,40));
use a hash (#) to make fields and methods private (firefox 90)
class NoAccess {
	#field = "private field"
	#method() {
		console.log('method is private');
	}
}
getters and setters
class Obj {
	name = "John";
	get name() {
		return this.name;
	}
	set name(value) {
		this.name = value;
	}
}
o.name = "Wick";
console.log(o.name);
inheritance
class Child extends Parent {
	constructor(name) {
		super(name);
	}
}
protecting objects
Object.preventExtensions(object)
Object.isExtensible(object)
Object.seal(object)
Object.isSealed(object)
Object.freeze(object)
Object.isFrozen(object)

objects

new empty opbject
var o = new Object();
object literal
var o = {
    variableA: "A",
    variableB: "B",
};
object literal with method
var o = {
    variableA: "A",
    nethodName : function() {
        return "hello " + this.variableA;
    }
};
adding a method to an existing object
obj.min = Math.min;
obj.sum = function(a,b) { return a + b; }
accessing a property
console.log(o.variableA);
console.log(o["variableA"]);
standard methods
o.hasOwnProperty("variableA");         true iff has non-inherited property
o.isPropertyEnumerable("variableA");   true iff property is enumerable
o.toString();                          returns string representation
o.valueOf();                           returns primitive representation

prototypes

add a method to a prototype available for all objects created with that function
function func(){}
func.prototype.sum = function(a,b) { return a+b; }
p = new func();
console.log(p.sum(1,2));

JSON

convert string to object
JSON.parse(str);
convert object to string
JSON.stringify(obj);
convert Date to JSON
new Date().toJSON();

dom

dom structure
window
|-document
|-frames
|-history
|-location
|-navigator
|-parent
|-screen

history

navigate using the browser history
history.back();
history.forward();
history.go(-2);
history.go(2);

navigator

navigator attributes
navigator.appName          browser simple name (Netscape)
navigator.appVersion       browser version number
navigator.userAgent        browser full version name
navigator.appCodeName      browser code name (Mozilla)
navigator.platform         OS (windows / linux)

location

go to url
location.href = 'http://www.example.com'
location = 'http://www.example.com'
go to url and overwrite browser history
location.replace(url)
reload page
location.reload();
get full url of current page
location.href
get protocol only (http|https)
location.protocol
get domain name only
location.hostname
get path only
location.pathname
get querystring only (after ?)
location.query
get anything trailing the optional # in the url (or empty string)
location.hash
scroll to anchor tag
<a id="first">scroll</a>
location.hash=#first

<a name="second">scroll</a>
location.hash=#second

screen

screen attributes
screen.width           current os window width
screen.height          current os window height
screen.availWidth      window resolution width (if no security)
screen.availHeight     window resolution height (if no security)

stylesheet

disable stylesheet
document.styleSheets[0].disabled=true
disable all stylesheets
var collection = document.getElementsByTagName("link");
for(var i=0; i<collection.length; i++) {
	collection[i].disabled = true;
}

window

window attributes
window.innerWidth       viewport width
window.innerHeight      viewport height
window.outerWidth       os window width
window.outerHeight      os window height
window.screenX          os window position
window.screenY          os window position
window.devicePixelRatio scaling: device pixels / css pixels

window.pageXOffset      vertical scrollbar position
window.pageYOffset      horizonal scrollbar position
open a window
var ref = window.open();
var ref = window.open('http://eriklievaart.com');
var ref = window.open(url, target, features);
closing a window
window.close();
ref.close();
scrolling
window.scrollTo(x, y);           scroll to absolute position to upper left
window.scrollBy(dx, dy);         scroll pixels relative to current position
or ensure the specified element is visible
document.getElementById(200).scrollIntoView();

document

document attributes
domain
referrer
URL

anchors[]
forms[]
images[]
links[]
lookup first match in dom using css selector
var node = document.querySelector("[selector]");
lookup in dom using tag name
var collection = document.getElementsByTagName("[tag]");
lookup all matches in dom using css selector
var collection = document.querySelectorAll("[selector]");
insert into document while document is being rendered
document.write('<h1>hello</h1>');
change header text
document.getElementById('myheader').innerText = "change header text";
get text selected with mouse in document
var selected = document.getSelection().toString();
dynamically add import
var script = document.createElement("script");
script.src = 'https://code.jquery.com/jquery-3.6.0.min.js';
document.head.appendChild(script);

html element

HTMLElement attributes
id           id attribute
className    assigned css classes
dir
lang
style        inline style
title        <title> tag

innerHTML    used to read/write contents of a HTML element
outerHTML    can be used to replace the entirety of the HTML element
get and set HTML attribute value
hasAttribute(name)
getAttribute(name)
setAttribute(name, value)
dynamically change CSS inline style
document.getElementById(id).style.color='red';
document.getElementById(id).style.fontWeight='bold';
document.getElementById(id).style.textDecoration='underline';
document.getElementById(id).style.padding='10px 0px';
get current computed style for element
var computed = window.getComputedStyle(document.getElementById(id)).color;
var computed = window.getComputedStyle(document.getElementById(id)).paddingTop;
get a string representing all assigned classes
var clz = document.getElementById(id).className;
overwrite the assigned classes of an element with a new list
document.getElementById(id).className = newClasses;
replace contents of a HTML element
document.querySelector("[selector]").innerHTML = '<h1>hello</h1>';

tables

methods
createTBody()
insertRow(index?)
deleteRow(index)
row methods
insertCell(index?)
example: create table rows and cells
var table = document.querySelector("table");
for(let o=0; o<9; o++) {
	let row = table.insertRow();
	for(let i=0; i<18; i++) {
		let cell = row.insertCell();
		cell.appendChild(document.createTextNode(o + ':' + i));
	}
}
documentation
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement

images

accessing all images
var array = document.images
changing the image loaded in an image tag
img.src = url;

forms

accessing all the forms
var array = document.forms;
accessing all the form elements in a form
var array = document.forms[index].elements
methods on a form object
submit();
reset();

form elements

attributes
form
name
type
value
form element types
checkbox
fieldset
file
hidden
password
radio
select-multiple
select-one
submit
text
textarea
events
onclick
onchange
onfocus
onblur
additional events for input fields
onkeypress
onkeydown
onkeyup

example: accessing form elements by name

<form name="myform"><input name="myinput" type="submit"></form>
<script>document.myform.myinput.value = 'do something';</script>

example: getting the type of a form element

var t = document.myform.myinput.type;

example: dropping a specific option in a <select>

var t = document.myform.myselect.options[1] = null;

example: dropping options in a <select> (truncate)

var t = document.myform.myselect.options.length=cropLength;

events

DOM-0 events

event names

window events
onerror
document events
onload
onunload
form events
onblur
onchange
onfocus
onreset
onselect
onsubmit
key events
onkeydown
onkeypress
onkeyup
mouse events
onclick
contextmenu
onmousedown
onmousemove
onmouseout
onmouseover
referencing a dom object through legacy dom
<form name="huppel">
	<input type="input" name="defluppel" value="alpha" />
</form>
<script>document.write(document.huppel.defluppel.value);</script>

example: registering an event on a html element directly

<h1 onclick="alert('hello')">click me</h1>

example: run code after page is fully initialized

window.onload = function(e){
	alert('page fully initialized');
}

example: global error handling

window.onerror = function(message, url, lineNumber) {
	html = 'line:' + lineNumber + '<br/>' + message;
	document.getElementById('error-hook').innerHTML = html;
}

example: shutdown hook

window.onunload = function() {
	websocket.send('closing');
	websocket.close();
}

example: capture mouse click events

document.onclick = function(e) {
	console.log("don't touch me!");
}

example: catch key events

document.onkeydown = function (e) {
	console.clear();
	console.log('alt:' + e.altKey)
	console.log('ctrl:' + e.ctrlKey)
	console.log('shift:' + e.shiftKey)
	console.log(e.key + ':' + e.code);
};
key codes for key events
https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
http://rmhh.co.uk/ascii.html
http://keycode.info/

DOM-2 events

event names

window events
resize
scroll
document events
load
scroll
unload
form events
blur
change
focus
reset
select
submit
key events
keydown
keypress
keyup
mouse events
click
mousedown
mousemove
mouseout
mouseover

related methods

addEventListener(event, function, capturing);
removeEventListener(event, function, capturing);

Event object

properties
type                      event name
target                    recipient of event
currentTarget             current element handling event
eventPhase                Event.CAPTURING_PHASE, Event.AT_TARGET or Event.BUBBLING_PHASE
timeStamp                 timestamp
bubbles                   boolean
cancelable                boolean
methods available in listeners
preventDefault();         don't run default action of event
stopPropagation();        consume event, don't bubble up stack

MouseEvent object

button            0=LMB 1=MMB 2=RMB
detail            contains click count
clientX           mouse X
clientY           mouse Y
screenX           desktop X
screenY           desktop Y
relatedTarget     used when a mouse event related to more than one element

altKey            boolean, holding alt?
ctrlKey           boolean, holding ctrl?
metaKey           boolean, holding meta?
shiftKey          boolean, holding shift?

example: listen to window resize events

window.addEventListener('resize', function(event) {
	h = window.innerHeight;
	w = window.innerWidth
	console.log("h = " + h, "; w = " + w, 10, 20);
});

example: add a window onload event

window.addEventListener('load', function(event) {
	console.log('document ready');
});

example: RMB / oncontextmenu

document.getElementById(id).addEventListener('contextmenu', function(e) {
	this.style = 'display:none;';
	e.preventDefault();
});

AJAX

fetch API hello world
fetch(url).then(response => {
	if(response.ok) {
		return (response.text());
	}
}).then(text => {
	document.getElementById('test').innerHTML = text;
});
documentation
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

scriptlets

delay event until user stops typing

function delay(millis, callback) {
  var timer = 0;
  return function() {
    var context = this, args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function () {
      callback.apply(context, args);
    }, millis);
  };
}
example usage
document.getElementById('foo').onkeypress(delay(500, function (e) {
	alert('foo');
}));

get position of element in window

// get X position of element, respecting scrollbars
function getX(e) {
	var scrolled = 0;
	var x=0;
	var p = e.parentNode;
	while(p && p != document.bodx) {
		if(p.scrollLeft) {
			scrolled += p.scrollLeft;
		}
		p = p.parentNode;
	}
	while(e) {
		x = x + e.offsetLeft;
		e = e.offsetParent;
	}
	return x - scrolled;
}

// get Y position of element, respecting scrollbars
function getY(e) {
	var scrolled = 0;
	var y=0;
	var p = e.parentNode;
	while(p && p != document.body) {
		if(p.scrollTop) {
			scrolled += p.scrollTop;
		}
		p = p.parentNode;
	}
	while(e) {
		y = y + e.offsetTop
		e = e.offsetParent;
	}
	return y - scrolled;
}

Javascript Introspection

function introspect(introspectMe, message) {
    var functions = [];
    var objects = [];
    var properties = [];

    for(prop in introspectMe) {
        value = introspectMe[prop];
        type = typeof(value);

        if(type == 'function') {
            functions.push(prop);
        } else if(type == 'object') {
            objects.push(prop);
        } else {
            properties.push(prop + '[' + type + '] = ' + value);
        }
    }

    if(message) {
        window.console.log(message);
    }
    window.console.log('objects: ' + objects.toString());
    window.console.log('functions: ' + functions.toString());
    for(i=0; i<properties.length; i++) {
        window.console.log(properties[i]);
    }
    window.console.log();
}
dragging an absolute positioned html element
<span style="position:absolute; left:10px; top:10px; background-color:#00F; width:100px; height:100px;"></span>
<span style="position:absolute; left:120px; top:10px; background-color:#F00; width:100px; height:100px;"></span>

<script>
dragging = {};
draggable = document.getElementsByTagName('span');
for(var i=0; i<draggable.length; i++) {
	draggable[i].addEventListener("mousedown", function(e) {
		dragging.element = e.target;
		e.stopPropagation();
		e.preventDefault();
	});
	document.addEventListener("mousemove", function(e) {
		e.stopPropagation();
		if(dragging.element) {
			dragging.element.style.left = e.clientX-50 + 'px';
			dragging.element.style.top  = e.clientY-50 + 'px';
		}
	});
	document.addEventListener("mouseup", function(e) {
		e.stopPropagation();
		delete dragging.element;
	});
}
</script>