Document Object Model (DOM)
Selecting DOM Elements
Get Element(s)
Get element nodes for HTML tag, class, or id
document.body
document.getElementsByTagName("p");
document.getElementsByClassName("class");
document.getElementById("id");
Query Selector
returns the first instance for this query
document.querySelector("div.selected")
returns a node list of elements for this query
document.querySelectorAll(".selected")
// convert node list to array
const list1 = Array.from(document.querySelectorAll(".element"));
const list2 = [...document.querySelectorAll(".element")];
Matches query
e.target.matches("div")
Accessing element node's properties
Nodes
const element = document.createElement("span");
const text = document.createTextNode("hallo")
element.parentNode
element.parentElement
element.firstChild
element.lastChild
parent.append("Hello from JS")
parent.append(element)
parent.appendChild(element)
element.remove()
parent.removeChild(element)
element.innerHTML
element.textContent // text including whitespace from HTML structure
element.innerText // simple text
element.content
element.value
element.tagName // == 'SPAN' || == 'VIDEO'
element.nodeType // == Node.TEXT_NODE || == Node.ELEMENT_NODE
insertAdjacentHTML
const childHTMLString = "<img src='bird.png' alt='bird'>";
parentElement.insertAdjacentHTML("beforeend", childHTMLString);
element.replaceWith(node)
textContent
document.getElementById("gamebutton").textContent = "Restart Game!";
content
const templateContent = document.getElementsByTagName("template")[0].content;
appendChild
const childImage = document.createElement("img");
childImage.src = "butterfly.png";
parent.appendChild(childImage);
cloneNode
const template = document.createElement("template");
template.innerHTML = `<h3>Title</h3>`;
const node = template.content.cloneNode(true);
Node
document.createTextNode(text)
node.textContent = '123'
nodeA.parentNode.insertBefore(nodeB, nodeA) // nodeB - nodeA
nodeA.parentNode.insertBefore(nodeB, nodeA.nextSibling) // nodeA - nodeB = insertAfter (which does not exist)
node.after(document.createElement('span'))
Attributes
element.setAttribute("tabindex", -1)
element.getAttribute("src")
element.removeAttribute("class")
// image attributes
element.src
element.alt
// data attributes – <span data-index="1" data-vegetable-variety="spinach">Spinach</span>
element.dataset
element.dataset.index
element.dataset.vegetableVariety
Classes
element.className
element.classList.add("new-class")
element.classList.add("mystyle", "anotherClass", "thirdClass")
element.classList.remove("highlight")
element.classList.contains('zoom')
element.classList.toggle("switched-on")
element.classList.toggle("switched-on", false)
element.classList.toggle("switched-on", el.width > 120)
element.classList.value
element.classList.length
element.classList.item(0)
Style
element.style.display = "block";
element.style.border = "1px solid blue";
element.style.marginLeft = 0;
element.style.animationPlayState = `paused`;
element.style.setProperty("background", "#fff");
element.style.setProperty("--cursorY", e.offsetY + "px");
element.style.removeProperty("--cursorY");
document.documentElement.style.cssText = `color: red;`;
const computedStyle = window.getComputedStyle(element);
computedStyle.getPropertyValue('margin')
StyleSheets
document.styleSheets /* – stylesheets associated with a page */
document.styleSheets[0].cssRules
document.styleSheets[0].cssRules[0].type
document.styleSheets[0].cssRules[0].deleteRule(rule)
document.styleSheets[0].cssRules[0].appendRule(rule)
DOM Traversal
element.parentNode
element.nextSibling
element.firstChild
element.lastChild
element.closest('button:not(.user)')
element.closest('dialog')
Cloning a node (pass parameter true
for deep copy)
const clonedNode = document.querySelector("#picture_template").cloneNode(true);
parent.appendChild(clonedNode);
Measurements and Scroll
Screen Measurements
window.innerWidth
window.innerHeight
window.outerWidth
window.outerHeight
window.screenX
window.screenY
window.screenLeft
window.screenTop
window.pageXOffset
window.pageYOffset
window.scrollX
window.scrollY
window.screen // width, height, availWidth, availHeight, availLeft, availTop, isExtended, orientation
window.devicePixelRatio
Element Measurements
element.getClientRects() // more than one for e.g. inline-level elements
element.getBoundingClientRect().top // x, y, width, height, top, right, bottom, left
element.offsetParent // parent with position != `static`
element.offsetTop // `block`-level: position of border-box, `inline`-level: position of FIRST border-box
element.offsetLeft
element.offsetHeight
element.offsetWidth
jQuery's offset()
in Vanilla JS
var rect = document.querySelector("#container").getBoundingClientRect();
var offset = {
top: rect.top + window.scrollY,
left: rect.left + window.scrollX,
};
console.log(offset);
element.clientTop
element.clientLeft
element.clientHeight
element.clientWidth
document.elementFromPoint(x, y)
Scroll
window.scroll({ top: 100, behavior: "smooth" })
window.scrollTo({ top: 100, behavior: "smooth" })
window.scrollBy(dx, dy)
window.scrollBy({ top: 100, behavior: "smooth" })
element.scrollIntoView(true) // align to top
element.scrollIntoView(false) // align to bottom
element.scrollIntoView({ block: "start", behavior: "smooth" })
element.scrollIntoView({ inline: "center", behavior: "smooth" })
Text Manipulation
Writing to the document
document.write("");
Text Selection
Selection
const selection = window.getSelection();
const selection = document.getSelection();
selection.isCollapsed // true / false
selection.empty()
selection.removeAllRanges()
selection.addRange(range)
selection.modify(alter, direction, granularity)
selection.modify("extend", "backward", "word")
selection.modify("extend", "forward", "word")
selection.modify("move", "forward", "line")
selection.modify("move", "forward", "lineboundary")
selection.modify("move", "forward", "character")
if (selection.type == "Range") return;
if (selection.type == "Caret") return;
Range
const range = selection.getRangeAt(0)
const range = new Range()
range.selectNodeContents(element)
range.commonAncestorContainer
range.startContainer
range.endContainer
range.startOffset
range.endOffset
range.collapsed // true / false
range.setStart(node, offset)
range.setEnd(node, offset)
range.setStart(element, 12)
node
– text node or an element node- If
node
is a text node, thenoffset
must be the position in the text. - If
node
is an element node, thenoffset
must be the child number.
Selection events
// attention: different behaviour on touch screens and desktops
document.addEventListener("selectionchange", function() {});
// better use pointer events for universal behaviour
document.addEventListener("mouseup", function() {});
document.addEventListener("touchend", function() {});
document.addEventListener("touchcancel", function() {});
Input and text fields
Select contents of a text field
document.querySelector("input").select();
Document Fragment
let fragment = new DocumentFragment()
for (let i = 1; i < 3; i++) {
let li = document.createElement("li")
li.innerHTML = i
fragment.appendChild(li)
}
let list = document.querySelector("ul")
list.appendChild(fragment)
Separate HTML Document
const doc = document.implementation.createHTMLDocument();
doc.write('<div>'):
document.body.append(doc.body.firstChild);
// Stream HTML contents (div in the body will automatically update)
doc.write('<p>Hello'):
doc.write('world!</p>');
doc.write('<p>Yay!</p>');
doc.write('</div>'):
Event Listeners
window.addEventListener("load", () => alert("loaded DOM"));
For details see Event Listeners.
Mouse: click
, contextmenu
, dblclick
, mousedown
, mouseenter
, mouseleave
, mousemove
, mouseover
, mouseout
, mouseup
mousewheel
, wheel
,
Touch: touchstart
, touchmove
, touchcancel
, touchend
Pointer: pointerdown
, pointermove
, pointerover
, pointerout
, pointerenter
, pointerleave
, pointerup
Gesture: gesturestart
, gesturechange
, gestureend
Keyboard: keydown
, keypress
, keyup
Device: devicemotion
, deviceorientation
, orientationchange
Frame: load
, abort
, error
, beforeunload
, unload
,
pageshow
, pagehide
,
hashchange
,
resize
,
scroll
Form: change
, input
, select
,
focus
, focusin
, focusout
, blur
,
invalid
, reset
, search
, submit
Drag: drag
, dragstart
, dragend
, dragenter
, dragleave
,
drop
Animation: animationstart
, animationend
, animationiteration
Animation: animationstart
, animationend
, animationiteration
,
transitionend
Media: abort
, error
, waiting
, canplay
,
durationchange
,
loadstart
, loadedmetadata
, canplaythrough
, loadeddata
,
play
, pause
, playing
, ended
,
progress
,
timeupdate
,
ratechange
,
seeked
,
seeking
,
stalled
,
suspend
,
volumechange
Misc:
message
,
online
, offline
,
popstate
,
show
,
storage
,
toggle
,
Root object window
Properties
window.document
window.console
Methods
window.alert()
Properties of the window
object don't need to be specified.
window.setTimeout(() => {
window.alert("Hi");
}, 3000)
setTimeout(() => {
alert("Hi");
}, 3000)
call parent
function from within iFrame
parent
= parent's window
// in document
function my_function() {
// ...
}
// in iframe
parent.my_function()
Browser APIs
window.navigator
window.history
window.localStorage
window.sessionStorage
document.cookie
For details see Browser APIs.
Which Browser am I running on?
navigator.userAgent
Other useful details
navigator.appCodeName
navigator.appName
navigator.appVersion
navigator.cookieEnabled
navigator.platform
navigator.systemLanguage
Browser
Get all browser windows (not tabs)
await browser.windows.getAll()
DOMPoint
and DOMMatrix
const point = new DOMPoint(10, 20)
const matrix = new DOMMatrix("translate(10px, 15px)").rotate(30)
matrix.transformPoint(point)
Draw a star mask
const createStar = ({ points = 5, x = 0, y = 0, size = 1 }) => {
Array.from({ length: points * 2 }, (_, i) =>
new DOMMatrix()
.translate(x, y)
.scale(size)
.rotate((i / points) * 360)
.translate(0, i % 2 ? -1 : -2)
.transformPoint({ x: 0, y: 0 })
)
}
function toCSSPolygon(points) {
const pointsStr = points.map(point => `${point.x}px ${point.y}px`).join(', ')
return `polygon(${pointsStr})`
}
const rect = el.getBoundingClientRect() ;
const x = rect.width / 2:
const y = rect.height / 2;
const endSize = Math.sqrt(x**2 + y**2);
el.animate({
clipPath: [
toCSSPolygon(createStar({ x, y, size: 0 })),
toCSSPolygon(createStar({ x, y, size: endSize })),
]
}, { duration: 500, easing: "ease-in" });
Feature detection
if (browser.contextMenus) {
browser.contextMenus.create({ title: "Options...", ... })
}
if ("IntersectionObserver" in window) {
// ...
}
setTimeout
, setInterval
and requestAnimationFrame
Functions
setTimeout(callback, timeout)
window.clearTimeout(myTimeout)
setInterval(callback, interval)
window.clearInterval(myInterval)
requestAnimationFrame(callback)
setTimeout
var to = setTimeout(timeoutDone, 3000);
function timeoutDone() {
alert("Your three seconds are up!");
}
function someEventToCancelTheTimeout() {
clearTimout(to);
}
setInterval
var myVar = setInterval(timer, 1000);
function timer() {
var d = new Date();
var t = d.toLocaleTimeString();
console.log(t);
}
function stopFunction() {
clearInterval(myVar);
}
requestAnimationFrame
function animationStep(time) {
// do some animations
requestAnimationFrame(animationStep);
}