WebDev Bites: JavaScript

event handling

Definition
JavaScript (ES6) specification A programming language based on objects composed of key-value pairs. Keys are names, and values may be a function (pointer), a literal, or another object.
Figure 1. Object Prototype Chain
JavaScript uses a prototype model to support specialization. If a function call can't be resolved on an object, function lookup walks up the object's prototype chain.
Jim = {
  "Name":"Fawcett",
  "Job":"Instructor,
  ...
}

Figure 2. JavaScript Execution Engine
When a JavaScript function is called its context (a JavaScript object) is loaded into an Execution Stack. When an event fires the context of its event handler function is enqueued in an Event Message Queue. Handlers don't execute until all functions have completed. Then, its context is loaded into the Execution Stack for processing.
Basic syntax overview:

let obj = new Object;
obj.name = "Frank E. Stein";
obj.show = function() {
  return "obj { " + `${obj.name}` + " }"
}
console.log(obj.show());

// output is: obj { Frank E. Stein }

onlinejsplayground.com
JavaScript Syntax This content was generated by ChatGPT from the prompt: "give a brief discussion of JavaScript syntax with small examples".
--- Values, variables, and scope ---

// Numbers, strings, booleans, null, undefined, BigInt, Symbol
let n = 42, s = "hi", ok = true, z = null;

// Prefer let/const over var (block vs function scope)
const PI = 3.1416;    // cannot be reassigned
let count = 0;        // can be reassigned

--- Expressions and operators ---

// Math, comparison, logical
1 + 2 * 3;            // 7
10 ** 2;              // 100 (exponent)
a === b;              // strict equality (no coercion)
a && b || c;          // short-circuiting

// Nullish coalescing & optional chaining
const name = user.name ?? "Anonymous";
const city = user.address?.city;  // undefined if any link is missing

--- Control flow ---

if (x > 0) { ... } else { ... }

for (let i = 0; i < 3; i++) { ... }
for (const v of [1,2,3]) { ... }          // iterable loop
while (cond) { ... }

switch (kind) {
  case "cat": doCat(); break;
  default: fallback();
}

--- Function declarations, expressions, lambdas ---

function add(a, b = 0) { return a + b; }   // default param

const mul = function(a, b) { return a * b; }; // expression

const dbl = x => x * 2;                    // arrow (lexical `this`)

--- Objects and arrays ---

const person = { id: 1, name: "Ada" };
const team = ["A", "B", "C"];

// Destructuring
const { name } = person;
const [first, ...rest] = team;

// Shorthand & computed keys
const x = 1, y = 2;
const point = { x, y, ["p" + "3"]: 3 };

// Spread/merge
const withAge = { ...person, age: 36 };
const bigger = [...team, "D"];

--- Template literals ---

const who = "world";
const msg = `Hello, ${who}!
This spans multiple lines.`;

--- Classes (ES2015+) ---

class Counter {
  #n = 0;                     // private field
  inc() { this.#n++; }
  get value() { return this.#n; }
  static from(n) { const c = new Counter(); c.#n = n; return c; }
}

--- Modules ---

// export.js
export const PI = 3.14;
export default function area(r){ return PI * r * r; }

// import.js
import area, { PI } from "./export.js";

--- Promises and async/await ---

// Promise chain
fetch("/api/user")
  .then(r => r.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// async/await
async function load() {
  try {
    const r = await fetch("/api/user");
    const data = await r.json();
    console.log(data);
  } catch (e) {
    console.error(e);
  }
}

--- Errors and try/catch ---

try {
  risky();
} catch (err) {
  console.error(err.message);
} finally {
  cleanup();
}

--- DOM basics ---

const btn = document.querySelector("#go");
btn.addEventListener("click", () => {
  document.body.style.backgroundColor = "papayawhip";
});

--- Truthy / falsey & equality ---

// falsey: false, 0, -0, 0n, "", null, undefined, NaN
if ("0") { /* runs: non-empty strings are truthy */ }

// Prefer === to avoid coercion surprises
"5" == 5   // true  (coerces)
"5" === 5  // false (strict)

JavaScript is usually used in one of three ways:
  1. Create functions that manipulate the DOM when user events occur, like:
    <div id="demo" onclick="toggle('demo')">Hello World</div>
  2. Create objects that manage menus used by many pages. When changes are needed there is only one place to change instead of visiting every page.
  3. Create objects that manage complex things like visual widgets by holding and mutating object state.
Methods and properties are appended with simple declarations as shown in the JavaScript Syntax block above.
JavaScript Object This table was generated by ChatGPT from the prompt: "create a table containing methods and properties of the JavaScript Object type"
Signature Brief description Example
Static properties (on Object)
Object.prototypeBase prototype of plain objectsObject.prototype.hasOwnProperty.call(o,'x')
Object.lengthFormal parameters count (1)Object.length === 1
Object.nameFunction nameObject.name === 'Object'
Static methods (on Object)
Object.assign(target, ...sources)Shallow copy/mergeObject.assign({}, a, b)
Object.create(proto[, props])Create with prototypeconst o = Object.create(null)
Object.defineProperty(obj, key, desc)Define 1 propertyObject.defineProperty(o,'id',{value:1,writable:false})
Object.defineProperties(obj, descs)Define manyObject.defineProperties(o,{a:{value:1},b:{value:2}})
Object.entries(obj)[[key,value]] arrayObject.entries(o).forEach(([k,v])=>...)
Object.fromEntries(iter)Entries → objectObject.fromEntries(new URLSearchParams(qs))
Object.values(obj)Enumerable valuesObject.values(o).includes(42)
Object.keys(obj)Enumerable keysfor (const k of Object.keys(o)) {...}
Object.getOwnPropertyNames(obj)Own string keysObject.getOwnPropertyNames(o)
Object.getOwnPropertySymbols(obj)Own symbol keysObject.getOwnPropertySymbols(o)
Object.getOwnPropertyDescriptor(obj, key)Descriptor of keyObject.getOwnPropertyDescriptor(o,'x')
Object.getOwnPropertyDescriptors(obj)All descriptorsObject.getOwnPropertyDescriptors(o)
Object.getPrototypeOf(obj)Read prototypeObject.getPrototypeOf(o) === Foo.prototype
Object.setPrototypeOf(obj, proto)Set prototypeObject.setPrototypeOf(o, null)
Object.is(a, b)SameValue compareObject.is(NaN, NaN) === true
Object.seal(obj)Block add/remove propsObject.seal(o)
Object.isSealed(obj)Sealed?Object.isSealed(o)
Object.freeze(obj)Make immutable (shallow)Object.freeze(config)
Object.isFrozen(obj)Frozen?Object.isFrozen(config)
Object.preventExtensions(obj)Disallow new propsObject.preventExtensions(o)
Object.isExtensible(obj)Extensible?Object.isExtensible(o)
Object.hasOwn(obj, key)Own key present?Object.hasOwn(o, 'id')
Prototype methods (on Object.prototype)
obj.hasOwnProperty(key)Own key checko.hasOwnProperty('x')
obj.propertyIsEnumerable(key)Enumerable?o.propertyIsEnumerable('x')
obj.isPrototypeOf(value)In prototype chain?Foo.prototype.isPrototypeOf(inst)
obj.toString()Tag/legacy stringObject.prototype.toString.call([]) // "[object Array]"
obj.toLocaleString()Locale stringdate.toLocaleString('en-US')
obj.valueOf()Primitive hintnew Number(5).valueOf() === 5
Prototype properties / accessors
obj.__proto__ (getter/setter)Legacy proto accessobj.__proto__ = null (prefer get/setPrototypeOf)
obj.constructorRef to constructoro.constructor === Object
Legacy utilities (non-standard / discouraged)
obj.__defineGetter__(key, fn)Define gettero.__defineGetter__('x', () => 42)
obj.__defineSetter__(key, fn)Define settero.__defineSetter__('x', v => log(v))
obj.__lookupGetter__(key)Lookup gettero.__lookupGetter__('x')
obj.__lookupSetter__(key)Lookup settero.__lookupSetter__('x')
JavaScript is primarily used to observe and mutate elements in a web page document. The table within provides most of the methods that support these activities.
JavaScript Methods and Properties This table was generated by ChatGPT from the prompt: "Create a table of JavaScript methods and properties with three columns. The first has method or property signature, the second contains a very brief description, and the third has an example"
Signature Brief description Example
Selection & traversal
document.querySelector(sel)First matchconst el = qs('#app')
document.querySelectorAll(sel)NodeList of matches[...qsa('.item')]
document.getElementById(id)By idgebi('nav')
element.closest(sel)Nearest ancestor matchbtn.closest('form')
element.matches(sel)Element matches selector?if (el.matches('.active')) { … }
element.parentElementParent nodeel.parentElement.remove()
element.childrenHTMLCollection of children[...el.children].length
Events
element.addEventListener(type, fn, opts)Listen for eventsel.addEventListener('click', onClick, { once:true })
element.removeEventListener(type, fn, opts)Stop listeningel.removeEventListener('click', onClick)
element.dispatchEvent(evt)Fire custom eventel.dispatchEvent(new Event('refresh'))
Classes & attributes
element.classList.add(...tokens)Add class(es)el.classList.add('active')
element.classList.remove(...tokens)Remove class(es)el.classList.remove('hidden')
element.classList.toggle(token[, force])Toggle classel.classList.toggle('open', isOpen)
element.classNameClass stringel.className = 'card raised'
element.setAttribute(name, value)Set attributeel.setAttribute('aria-live','polite')
element.getAttribute(name)Read attributeel.getAttribute('role')
element.removeAttribute(name)Remove attributeel.removeAttribute('disabled')
element.hasAttribute(name)Has attribute?el.hasAttribute('hidden')
Content & DOM mutation
element.textContentSet/read textel.textContent = 'Hello'
element.innerHTMLSet/read HTMLel.innerHTML = '<b>Hi</b>'
element.insertAdjacentHTML(pos, html)Insert HTMLel.insertAdjacentHTML('beforeend','<li>…</li>')
element.append(...nodes)Append nodes/textel.append(child)
element.prepend(...nodes)Prepend nodesel.prepend(title)
element.replaceWith(node)Replace selfel.replaceWith(newEl)
element.remove()Detach from DOMel.remove()
document.createElement(tag)New elementconst div = ce('div')
Styles
element.style.propInline style propertyel.style.backgroundColor = '#222'
style.setProperty(name, value, priority?)Set (incl. !important)el.style.setProperty('margin','0','important')
style.getPropertyValue(name)Read inline valueel.style.getPropertyValue('--gap')
getComputedStyle(el[, pseudo])Resolved stylesgetComputedStyle(el).color
Stylesheets (CSSOM)
document.styleSheetsList of sheetsconst sheet = document.styleSheets[0]
sheet.insertRule(rule, i)Add CSS rulesheet.insertRule('.box{gap:8px}', sheet.cssRules.length)
sheet.deleteRule(i)Remove rulesheet.deleteRule(0)
new CSSStyleSheet()Constructable sheetconst s = new CSSStyleSheet()
sheet.replaceSync(text)Replace contentss.replaceSync(':root{--c:#09f}')
document.adoptedStyleSheetsAdopt sheetsdocument.adoptedStyleSheets = [...document.adoptedStyleSheets, s]
Geometry & scrolling
element.getBoundingClientRect()Box metricsconst {top} = el.getBoundingClientRect()
element.scrollIntoView(opts)Scroll to elementel.scrollIntoView({ behavior:'smooth' })
window.scrollX / scrollYPage scroll offsetsif (scrollY > 100) { … }
Media queries & animation
matchMedia(query)Watch media statematchMedia('(prefers-color-scheme:dark)').matches
element.animate(keyframes, options)Web Animationsel.animate({opacity:[0,1]}, 300)
Forms
form.requestSubmit()Programmatic submitform.requestSubmit()
form.reset()Reset controlsform.reset()
input.valueRead/write valuename.value = 'Ada'
checkbox.checkedBoolean stateagree.checked = true
Storage & network
localStorage.getItem/setItem/removeItemKey-value storagelocalStorage.setItem('theme','dark')
sessionStorage.getItem/…Per-tab storagesessionStorage.getItem('token')
fetch(url, options)HTTP requestsawait fetch('/api/data')
Timing
setTimeout(fn, ms) / clearTimeout(id)Delay a taskconst id = setTimeout(run, 200)
setInterval(fn, ms) / clearInterval(id)Repeat tasksetInterval(tick, 1000)
requestAnimationFrame(fn) / cancelAnimationFrame(id)Frame-syncedraf = requestAnimationFrame(step)
JavaScript supports inheritance with a prototype model, described briefly in the Definition block. JavaScript classes provide a syntax similar to other programming languages that simply wraps the prototype model.
JavaScript Classes (ES2015+) This example code was generated by ChatGPT from the prompt: "describe the new JavaScript class syntax".
class Point {
  // public instance fields (per instance, on `this`)
  x = 0;
  y = 0;

  constructor(x, y) {           // runs on `new Point(...)`
    this.x = x; this.y = y;
  }

  // prototype method (shared by instances)
  length() { return Math.hypot(this.x, this.y); }

  // getter/setter
  get r() { return this.length(); }
  set r(v) { const a = Math.atan2(this.y, this.x); this.x = v*Math.cos(a); this.y = v*Math.sin(a); }

  // static method (on the class constructor)
  static origin() { return new Point(0, 0); }
}

class Counter {
  #value = 0;                 // private instance field
  static #MAX = 1_000_000;    // private static field

  get value() { return this.#value; }
  #clamp(n) { return Math.min(n, Counter.#MAX); } // private method

  increment() { this.#value = this.#clamp(this.#value + 1); }

  static from(n) { const c = new Counter(); c.#value = c.#clamp(n); return c; }
}

// Presence check (only inside class that declares #value):
// if (#value in someObj) { ... }

class Animal {
  constructor(name) { this.name = name; }
  speak() { return `${this.name} makes a noise.`; }
}

class Dog extends Animal {
  constructor(name) { super(name); }          // must call super() before using `this`
  speak() { return `${super.speak()} Woof!`; } // call base method
}

class Config {
  static base = '/api';
  static #token;

  static {                       // runs once when class is evaluated
    this.#token = crypto.randomUUID?.() ?? 'dev-token';
  }

  static authHeader() { return { Authorization: `Bearer ${this.#token}` }; }
}

const Widget = class NamedWidget { /* ... */ }; // name usable inside the class body
class Greeter {
  ['say' + 'Hi']() { return 'hi'; }             // computed method name
  static ['v' + 1] = 2;                         // computed static field
}

class Timer {
  start = performance.now();
  label = `t-${this.start | 0}`;
}

class Base {
  constructor() {
    if (new.target === Base) throw new TypeError('Abstract');
  }
}

class Button {
  // Arrow keeps `this` bound without manual .bind()
  handleClick = (e) => { this.count++; };
  count = 0;
}
JavaScript has a rich collection of methods used to observe and manipulate a document's CSS styles. The methods given here operate on the static styles, e.g., as defined by static declarations.
Static JavaScript Styles This table was generated by ChatGPT from the prompt: "create a fixed layout table with colgroup that lists all of the styles. The first column hs CSS style name, the second column has JavaScript equivalent, and the third has a brief example of use in JavaScript".
CSS property JS (element.style.*) Example (JS)
--custom-propsetProperty / getPropertyValueel.style.setProperty('--brand', '#0af')
allallel.style.all = 'unset'
colorcolorel.style.color = 'rebeccapurple'
backgroundbackgroundel.style.background = 'linear-gradient(#000,#333)'
background-colorbackgroundColorel.style.backgroundColor = 'tomato'
background-imagebackgroundImageel.style.backgroundImage = "url('bg.png')"
background-positionbackgroundPositionel.style.backgroundPosition = 'center 20%'
background-sizebackgroundSizeel.style.backgroundSize = 'cover'
background-repeatbackgroundRepeatel.style.backgroundRepeat = 'no-repeat'
background-clipbackgroundClipel.style.backgroundClip = 'text'
background-originbackgroundOriginel.style.backgroundOrigin = 'content-box'
opacityopacityel.style.opacity = '0.7'
fontfontel.style.font = "italic 600 1rem/1.4 Inter"
font-familyfontFamilyel.style.fontFamily = "Inter, system-ui, sans-serif"
font-sizefontSizeel.style.fontSize = '18px'
font-weightfontWeightel.style.fontWeight = '700'
font-stylefontStyleel.style.fontStyle = 'oblique'
font-stretchfontStretchel.style.fontStretch = 'condensed'
font-variantfontVariantel.style.fontVariant = 'small-caps'
line-heightlineHeightel.style.lineHeight = '1.6'
letter-spacingletterSpacingel.style.letterSpacing = '.02em'
word-spacingwordSpacingel.style.wordSpacing = '.1em'
text-aligntextAlignel.style.textAlign = 'center'
text-decorationtextDecorationel.style.textDecoration = 'underline wavy'
text-decoration-colortextDecorationColorel.style.textDecorationColor = '#09f'
text-transformtextTransformel.style.textTransform = 'uppercase'
text-overflowtextOverflowel.style.textOverflow = 'ellipsis'
white-spacewhiteSpaceel.style.whiteSpace = 'nowrap'
word-breakwordBreakel.style.wordBreak = 'break-word'
hyphenshyphensel.style.hyphens = 'auto'
text-shadowtextShadowel.style.textShadow = '0 1px 2px rgba(0,0,0,.3)'
directiondirectionel.style.direction = 'rtl'
writing-modewritingModeel.style.writingMode = 'vertical-rl'
tab-sizetabSizeel.style.tabSize = '4'
caret-colorcaretColorel.style.caretColor = 'auto'
accent-coloraccentColorel.style.accentColor = 'hotpink'
user-selectuserSelectel.style.userSelect = 'none'
widthwidthel.style.width = '320px'
heightheightel.style.height = '200px'
min-widthminWidthel.style.minWidth = '10rem'
max-widthmaxWidthel.style.maxWidth = '60ch'
min-heightminHeightel.style.minHeight = '100vh'
max-heightmaxHeightel.style.maxHeight = '80vh'
marginmarginel.style.margin = '1rem auto'
paddingpaddingel.style.padding = '16px'
borderborderel.style.border = '1px solid #ddd'
border-radiusborderRadiusel.style.borderRadius = '12px'
border-colorborderColorel.style.borderColor = '#ccc'
border-widthborderWidthel.style.borderWidth = '2px'
outlineoutlineel.style.outline = '2px solid #09f'
outline-offsetoutlineOffsetel.style.outlineOffset = '2px'
box-sizingboxSizingel.style.boxSizing = 'border-box'
box-shadowboxShadowel.style.boxShadow = '0 4px 12px rgba(0,0,0,.15)'
aspect-ratioaspectRatioel.style.aspectRatio = '16 / 9'
displaydisplayel.style.display = 'grid'
visibilityvisibilityel.style.visibility = 'hidden'
positionpositionel.style.position = 'absolute'
insetinsetel.style.inset = '0'
top / right / bottom / lefttop / right / bottom / leftel.style.top = '10px'
z-indexzIndexel.style.zIndex = '10'
floatcssFloatel.style.cssFloat = 'left'
clearclearel.style.clear = 'both'
overflowoverflowel.style.overflow = 'auto'
overflow-xoverflowXel.style.overflowX = 'hidden'
overflow-yoverflowYel.style.overflowY = 'scroll'
clip-pathclipPathel.style.clipPath = 'inset(10px)'
isolationisolationel.style.isolation = 'isolate'
pointer-eventspointerEventsel.style.pointerEvents = 'none'
cursorcursorel.style.cursor = 'pointer'
filterfilterel.style.filter = 'grayscale(1)'
backdrop-filterbackdropFilterel.style.backdropFilter = 'blur(8px)'
containcontainel.style.contain = 'layout paint'
will-changewillChangeel.style.willChange = 'transform'
mix-blend-modemixBlendModeel.style.mixBlendMode = 'multiply'
flex-directionflexDirectionel.style.flexDirection = 'row-reverse'
flex-wrapflexWrapel.style.flexWrap = 'wrap'
flex-flowflexFlowel.style.flexFlow = 'row wrap'
justify-contentjustifyContentel.style.justifyContent = 'space-between'
align-itemsalignItemsel.style.alignItems = 'center'
align-contentalignContentel.style.alignContent = 'space-around'
gapgapel.style.gap = '1rem'
row-gaprowGapel.style.rowGap = '.5rem'
column-gapcolumnGapel.style.columnGap = '2rem'
orderorderchild.style.order = '2'
flex-growflexGrowchild.style.flexGrow = '1'
flex-shrinkflexShrinkchild.style.flexShrink = '0'
flex-basisflexBasischild.style.flexBasis = '200px'
align-selfalignSelfchild.style.alignSelf = 'flex-end'
place-contentplaceContentel.style.placeContent = 'center'
place-itemsplaceItemsel.style.placeItems = 'start'
place-selfplaceSelfchild.style.placeSelf = 'stretch'
grid-template-columnsgridTemplateColumnsel.style.gridTemplateColumns = 'repeat(3, 1fr)'
grid-template-rowsgridTemplateRowsel.style.gridTemplateRows = 'auto 1fr auto'
grid-template-areasgridTemplateAreasel.style.gridTemplateAreas = '"h h" "m s" "f f"'
grid-auto-columnsgridAutoColumnsel.style.gridAutoColumns = 'minmax(0,1fr)'
grid-auto-rowsgridAutoRowsel.style.gridAutoRows = 'minmax(2rem, auto)'
grid-auto-flowgridAutoFlowel.style.gridAutoFlow = 'row dense'
grid-columngridColumnitem.style.gridColumn = '1 / 3'
grid-rowgridRowitem.style.gridRow = '2 / 4'
grid-areagridAreaitem.style.gridArea = 'header'
transformtransformel.style.transform = 'translateY(10px) scale(.9)'
transform-origintransformOriginel.style.transformOrigin = '50% 0'
transform-styletransformStyleel.style.transformStyle = 'preserve-3d'
perspectiveperspectiveel.style.perspective = '600px'
perspective-originperspectiveOriginel.style.perspectiveOrigin = 'center'
backface-visibilitybackfaceVisibilityel.style.backfaceVisibility = 'hidden'
transitiontransitionel.style.transition = 'opacity .3s ease'
transition-propertytransitionPropertyel.style.transitionProperty = 'transform'
transition-durationtransitionDurationel.style.transitionDuration = '200ms'
transition-timing-functiontransitionTimingFunctionel.style.transitionTimingFunction = 'cubic-bezier(.2,.8,.2,1)'
transition-delaytransitionDelayel.style.transitionDelay = '50ms'
animation-nameanimationNameel.style.animationName = 'pulse'
animation-durationanimationDurationel.style.animationDuration = '1.2s'
animation-iteration-countanimationIterationCountel.style.animationIterationCount = 'infinite'
animation-directionanimationDirectionel.style.animationDirection = 'alternate'
animation-timing-functionanimationTimingFunctionel.style.animationTimingFunction = 'ease-in-out'
animation-fill-modeanimationFillModeel.style.animationFillMode = 'both'
animation-play-stateanimationPlayStateel.style.animationPlayState = 'paused'
object-fitobjectFitimg.style.objectFit = 'cover'
object-positionobjectPositionimg.style.objectPosition = '50% 50%'
image-renderingimageRenderingel.style.imageRendering = 'pixelated'
list-stylelistStyleel.style.listStyle = 'square inside'
list-style-typelistStyleTypeel.style.listStyleType = 'decimal'
list-style-positionlistStylePositionel.style.listStylePosition = 'inside'
list-style-imagelistStyleImageel.style.listStyleImage = "url('bullet.svg')"
border-collapseborderCollapseel.style.borderCollapse = 'collapse'
table-layouttableLayoutel.style.tableLayout = 'fixed'
empty-cellsemptyCellsel.style.emptyCells = 'hide'
caption-sidecaptionSideel.style.captionSide = 'bottom'
columnscolumnsel.style.columns = '2 18rem'
column-countcolumnCountel.style.columnCount = '3'
column-gapcolumnGapel.style.columnGap = '1.5rem'
column-widthcolumnWidthel.style.columnWidth = '20rem'
column-rulecolumnRuleel.style.columnRule = '1px solid #ddd'
scroll-behaviorscrollBehaviorel.style.scrollBehavior = 'smooth'
overscroll-behavioroverscrollBehaviorel.style.overscrollBehavior = 'contain'
scroll-snap-typescrollSnapTypeel.style.scrollSnapType = 'x mandatory'
scroll-snap-alignscrollSnapAlignchild.style.scrollSnapAlign = 'center'
scroll-marginscrollMarginel.style.scrollMargin = '2rem'
scroll-paddingscrollPaddingel.style.scrollPadding = '2rem'
appearanceappearanceel.style.appearance = 'none'
visibilityvisibilityel.style.visibility = 'visible'
resizeresizeel.style.resize = 'both'
outline-styleoutlineStyleel.style.outlineStyle = 'dashed'
outline-widthoutlineWidthel.style.outlineWidth = '3px'
outline-coloroutlineColorel.style.outlineColor = 'crimson'
(any property) + !importantsetPropertyel.style.setProperty('margin','0','important')
The methods given here support observing and manipulating dynamic styles, e.g., with values that may have mutated during earlier processing.
Computed Styles This table was generated by ChatGPT from the prompt: "create a table that lists all of the methods and properties for handling dynamic styles".
Context / API Method / Property Purpose / Mini example
Inline styles (via element.style) — CSSStyleDeclaration
Inline style objectelement.styleAccess the element’s inline styles (writeable).
Set propertystyle.setProperty(name, value, [priority])el.style.setProperty('--brand','#0af','important')
Get propertystyle.getPropertyValue(name)style.getPropertyValue('--brand')#0af
Get prioritystyle.getPropertyPriority(name)Returns 'important' or ''
Remove propertystyle.removeProperty(name)style.removeProperty('--brand')
Enumeratestyle.length, style.item(i)Count & iterate property names.
Inline CSS textstyle.cssTextRead/replace all inline styles: style.cssText = 'color:red;'
Direct assignmentstyle.backgroundColor (camelCase)el.style.backgroundColor = 'tomato'
Class-based styling — DOMTokenList via element.classList
Token listelement.classListLive list of classes.
Add / removeadd(...tokens), remove(...tokens)el.classList.add('active','wide')
Toggletoggle(token[, force])el.classList.toggle('hidden', false)
Replacereplace(old, next)el.classList.replace('old','new')
Querycontains(token), item(i), lengthTest/inspect classes.
IterateforEach, values(), entries()Loop classes.
Whole stringelement.classNameGet/set the raw class attribute.
Computed styles — read resolved values
Get computedgetComputedStyle(element[, pseudo])const cs = getComputedStyle(el)cs.getPropertyValue('color')
Style attribute (raw)
Set / get / removesetAttribute('style', cssText), getAttribute('style'), removeAttribute('style')el.setAttribute('style','color:rebeccapurple')
Stylesheets & rules — CSSOM
All sheetsdocument.styleSheets (StyleSheetList)Enumerate attached stylesheets (including <style>/<link>).
Insert / delete ruleCSSStyleSheet.insertRule(rule, i), deleteRule(i)sheet.insertRule('.box{gap:1rem}', sheet.cssRules.length)
Replace textCSSStyleSheet.replace(text), replaceSync(text)Swap entire sheet (constructable sheets support both).
Rules listsheet.cssRules (CSSRuleList)Iterate rules: sheet.cssRules[i]
Enable/disablesheet.disabledTemporarily turn a stylesheet off.
Style ruleCSSStyleRule.selectorText, .styleChange selector or declarations of a rule.
Keyframes (sheet)CSSKeyframesRule.appendRule(), deleteRule(), findRule()Manipulate @keyframes at runtime.
Media ruleCSSMediaRule.conditionText, .cssRulesInspect rules under a media query.
Constructable stylesheets (modern)
Createnew CSSStyleSheet()Create a sheet in JS.
Populatesheet.replaceSync(text) / replace(text)sheet.replaceSync(':root{--c:#09f}')
Adopt (doc)document.adoptedStyleSheetsdocument.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]
Adopt (shadow)shadowRoot.adoptedStyleSheetsShare sheets across Shadow DOM roots.
CSS Custom Properties
Set / get / removestyle.setProperty('--x','10px'), getPropertyValue('--x'), removeProperty('--x')Scope to element (or document.documentElement for global).
CSS Typed OM (optional, newer)
Inline mapelement.attributeStyleMapWrite typed values: el.attributeStyleMap.set('opacity', 0.7)
Read computed mapelement.computedStyleMap()el.computedStyleMap().get('width') → typed value.
Map opsset, append, delete, get, getAll, has, clearManage style entries as a map.
Media queries in JS
QuerymatchMedia(query)const m = matchMedia('(prefers-color-scheme:dark)')
Listenm.addEventListener('change', fn)Respond to media changes; old: addListener/removeListener.
Web Animations API (programmatic CSS-like animation)
Animateelement.animate(keyframes, options)el.animate([{opacity:0},{opacity:1}], {duration:300})Animation
Controlanimation.play(), pause(), reverse(), finish(), cancel()Imperatively control visual state.
This collection displays a generous selection of API methods. For most web development the collection given in WebDevBites_HtmlDom.html provides what's needed in a much shorter table.
DOM API Methods
Category / Interface Key Methods / Properties Description Example
Node appendChild
removeChild
replaceChild
cloneNode
normalize
Base of DOM tree. Core manipulation of nodes (adding/removing/cloning) and normalization. const p = document.createElement('p');
document.body.appendChild(p);
Element getAttribute / setAttribute / removeAttribute / hasAttribute
querySelector / querySelectorAll
closest / matches
Represents element nodes; attribute access, querying descendants, selector matching, and traversal. const el = document.querySelector('.item');
if (el.matches('.active')) { /*...*/ }
HTMLElement focus() / blur() / click()
scrollIntoView()
getBoundingClientRect()
dataset
insertAdjacentHTML / insertAdjacentElement
HTML-specific element features: focus control, geometry, data-* access, and convenient insertion. el.dataset.id = '42';
el.scrollIntoView();
Document createElement
createTextNode
getElementById
querySelectorAll
body / head / documentElement
Root of DOM; create nodes, access top-level elements, and perform global queries. const div = document.createElement('div');
document.body.appendChild(div);
EventTarget addEventListener
removeEventListener
dispatchEvent
Event handling mechanism used by nodes: subscribe, unsubscribe, and emit events. el.addEventListener('click', e => console.log(e));
el.dispatchEvent(new Event('custom'));
Tree traversal / manipulation parentNode / children / childNodes
nextSibling / previousSibling
replaceWith / remove / prepend / append
Navigate and modify the DOM structure, including inserting and replacing elements. el.replaceWith(document.createElement('span'));
Selectors querySelector / querySelectorAll
getElementById / getElementsByClassName / getElementsByTagName
Find elements using CSS selectors or legacy collection methods (some live). const items = document.getElementsByClassName('card');
Attributes vs Properties setAttribute / getAttribute
property access (e.g., el.value)
dataset
Attributes are markup; properties are JS object fields. Reflection patterns sync them. el.setAttribute('data-role','admin');
console.log(el.dataset.role);
Events new Event / MouseEvent / CustomEvent
event.preventDefault()
event.stopPropagation()
Creation, dispatch, and handling of events. Supports bubbling, capturing, and delegation. el.addEventListener('submit', e => { e.preventDefault(); });
Shadow DOM attachShadow({mode})
<slot>
Encapsulation of markup/styles; slotting projects light DOM content into shadow DOM. const root = el.attachShadow({mode:'open'});
root.innerHTML = '<slot></slot>';
Custom Elements class X extends HTMLElement
customElements.define(name, constructor)
connectedCallback / disconnectedCallback / attributeChangedCallback / adoptedCallback
Define new HTML tags with lifecycle hooks and encapsulated behavior. customElements.define('my-widget', MyWidget);
MutationObserver new MutationObserver(callback)
observe(target, options)
Watch DOM changes (child list, attributes, subtree) and react programmatically. const obs = new MutationObserver(m => console.log(m));
obs.observe(el, { childList: true });
Geometry / Layout getBoundingClientRect()
window.getComputedStyle()
Measure element size/position and computed styles, essential for layout logic. const rect = el.getBoundingClientRect();
Class / Data helpers classList (add/toggle/contains/remove)
dataset
Utility accessors for manipulating CSS classes and data-* attributes easily. el.classList.toggle('active');
Templates <template>
template.content.cloneNode(true)
Define inert HTML fragments to instantiate multiple times without executing scripts. const tpl = document.getElementById('tpl');
document.body.appendChild(tpl.content.cloneNode(true));
DocumentFragment createDocumentFragment() Batch DOM insertions efficiently; fragment isn't rendered until appended. const frag = document.createDocumentFragment();
frag.appendChild(document.createElement('div'));
document.body.appendChild(frag);
CustomEvent new CustomEvent(type, { detail }) Dispatch events with structured payloads. el.dispatchEvent(new CustomEvent('update', { detail: { id: 5 } }));
window Object API This table was generated by ChatGPT from the prompt: "create a table listing the window object api"
Window API (signature) Brief description Example
Identity & globals
window / selfGlobal object in browsersself === window
top, parent, openerFrame tree refsif (window !== top) {/* in iframe */}
frames (array-like), length, frames[i] / frames['name'] Child frame windows collection & count; access by index or name (alias: window[i]). Cross-origin rules apply. for (let i = 0; i < frames.length; i++) frames[i].postMessage('ping','*')
nameWindow name (targeting)window.name = 'preview'
originScheme+host+portconsole.log(location.origin)
Document & DOM
documentActive documentdocument.title = 'Hello'
getSelection()Current text selectionconst sel = getSelection()
customElementsCustom elements registrycustomElements.define('x-box', Box)
getComputedStyle(el[, pseudo])Resolved stylesgetComputedStyle(el).color
Navigation
locationURL / navigationlocation.href = '/login'
historySession historyhistory.back(), history.go(1)
open(url, target, features)Open new window/tabopen('/help','_blank')
close()Close this windowwindow.close()
stop()Stop loadingwindow.stop()
Focus, dialogs, print
focus(), blur()Focus/defocus windowwindow.focus()
alert(msg)Modal alertalert('Saved')
confirm(msg)OK/Cancel dialogif (confirm('Delete?')) ...
prompt(msg[, def])Prompt for inputconst n = prompt('Name?')
print()Open print dialogprint()
Timers & scheduling
setTimeout(fn, ms) / clearTimeout(id)Run once after delayconst t = setTimeout(run, 200)
setInterval(fn, ms) / clearInterval(id)Run repeatedlysetInterval(tick, 1000)
queueMicrotask(fn)Microtask queuequeueMicrotask(flush)
requestAnimationFrame(fn) / cancelAnimationFrame(id)Frame-synced callbackraf = requestAnimationFrame(step)
requestIdleCallback(fn) / cancelIdleCallback(id)Idle-time workrequestIdleCallback(render)
Size, screen & viewport
innerWidth, innerHeightViewport sizeif (innerWidth < 768) {...}
outerWidth, outerHeightWindow outer sizeconsole.log(outerHeight)
devicePixelRatioCSS px → device pxif (devicePixelRatio>1) {...}
screenScreen infoscreen.availWidth
visualViewportVisual viewport APIvisualViewport.scale
Scrolling
scrollX / pageXOffset, scrollY / pageYOffsetScroll offsetsif (scrollY > 100) ...
scrollTo(x,y|opts), scrollBy(dx,dy|opts), scroll(opts)Programmatic scrollscrollTo({top:0, behavior:'smooth'})
Events
addEventListener(type, fn[, opts])Listen for eventsaddEventListener('resize', onResize)
removeEventListener(...)Stop listeningremoveEventListener('resize', onResize)
dispatchEvent(evt)Fire custom eventdispatchEvent(new Event('refresh'))
Common window eventsLifecycle/connectivityload, beforeunload, hashchange, popstate, online, offline, storage
Error handlersGlobal error captureonerror, onunhandledrejection
Messaging & queries
postMessage(msg, targetOrigin[, transfer])X-doc messagingother.postMessage({ok:true}, '*')
matchMedia(query)Media query statematchMedia('(prefers-color-scheme:dark)').matches
Networking & streams
fetch(input, init)HTTP requestsawait fetch('/api')
AbortController, AbortSignalCancel fetch/tasksconst c=new AbortController(); fetch(u,{signal:c.signal})
WebSocketRealtime socketnew WebSocket('wss://…')
Storage & data
localStorage / sessionStorageKey/value storagelocalStorage.setItem('theme','dark')
indexedDBClient DB (async)indexedDB.open('db',1)
cachesCacheStorageawait caches.open('v1')
structuredClone(value[, options])Deep structured cloneconst copy = structuredClone(obj)
Crypto & performance
crypto.getRandomValues(typedArray)CSPRNGcrypto.getRandomValues(new Uint8Array(16))
crypto.subtleWeb Crypto (SubtleCrypto)await crypto.subtle.digest('SHA-256', data)
performanceHigh-res timingsperformance.now()
URLs & encoding
URL, URLSearchParamsURL parsing/buildnew URL('/p', location.origin)
atob(str) / btoa(str)Base64 decode/encodeatob('SGk=')
Blob, File, FileReaderBinary/file APIsnew Blob(['hi'])
Workers & channels
Worker(url[, opts])Background threadnew Worker('/w.js')
SharedWorker(url[, opts])Shared backgroundnew SharedWorker('/sw.js')
BroadcastChannel(name)Tab-to-tab messagingnew BroadcastChannel('sync')
Environment & device
navigatorEnv capabilitiesnavigator.onLine
screen.orientationScreen orientationscreen.orientation.type
Common handler properties
onload, onbeforeunload, onresize, onscrollAssign event handlersonresize = () => layout()
onmessage, onerror, onunhandledrejectionMessaging & errorsonmessage = e => console.log(e.data)
Arguments for window.open(...)
Feature Example Description Default Modern Support
width width=600 Sets content area width in pixels. Browser default size Yes
height height=400 Sets content area height in pixels. Browser default size Yes
left left=100 Distance from left edge of screen. Centered Yes
top top=50 Distance from top edge of screen. Centered Yes
menubar menubar=no Show or hide browser menu bar. yes Partial
toolbar toolbar=no Show or hide navigation toolbar. yes Partial
location location=no Show or hide address bar. yes Partial
status status=no Show or hide status bar at bottom. yes Partial
scrollbars scrollbars=yes Allow or disallow scrollbars if needed. yes Yes
resizable resizable=yes Allow or prevent window resizing. yes Yes
fullscreen fullscreen=yes Open in full screen mode. no Limited
noopener noopener Block access to window.opener. no Yes
noreferrer noreferrer No Referer header; blocks opener. no Yes
directories directories=no Old: control bookmarks bar visibility. yes No
titlebar titlebar=no Old: hide window title bar. yes No
copyhistory copyhistory=yes Copy session history from source window. no Limited
Blogs and References The last 5 rows were added by ChatGPT 5 from the prompt:
"To the attached table add a link to the current ECMA spec and 4 other important references"
The original HTML table was pasted immediately below the prompt.
References
Reference Comments
Understanding data types in JavaScript Clear and complete
Understanding Objects in JavaScript Author Tania Rascia is a developer with a gift for explaining technical topics very clearly.
Prototypes and Inheritance Tania Rascia describes the JavaScript inheritance model in a thorough but simple way.
Modules, Import, and Export Modules help us factor complex code into simpler parts.
Event Loop, Callbacks, Promises, and Async/Await How JavaScript reacts to user events.
JavaScript tutorials list Contains links to the previous articles and many more.
ECMAScript® 2025 Language Specification (ECMA-262, 16th ed.) Normative HTML spec for the current ECMAScript edition (June 2025).
ECMA-262 Living Draft (Editor’s draft) Continuously updated draft reflecting approved and in-flight changes.
MDN JavaScript Reference Authoritative, task-oriented reference with examples and caveats.
MDN JavaScript Guide Big-picture language guide with how-tos and best practices.
TC39 ECMAScript Proposals (Stage 2+) Tracks features likely to land; useful for seeing what’s coming.