Chapter 1: Document
Browser environment, specs
A host environment provides own objects and functions additional to the language core.
Web browsers give a means to control web pages.
Node.js provides server-side features.
In browsers, there’s a “root” object called window
.
It is a global object for JavaScript code.
It represents the “browser window” and provides methods to control it.
DOM (Document Object Model)
Document Object Model, or DOM for short, represents all page content as objects that can be modified.
For example:
BOM (Browser Object Model)
The Browser Object Model (BOM) represents additional objects provided by the browser (host environment) for working with everything except the document.
The
navigator
object provides background information about the browser and the operating system. Example:navigator.userAgent
,navigator.platform
The
location
object allows us to read the current URL and can redirect the browser to a new one.
1.2 DOM tree
The backbone of an HTML document is tags.
According to the DOM, every HTML tag is an object. Nested tags are “children” of the enclosing one. The text inside a tag is an object as well.
DOM structure
Every tree node is an object.
Spaces and newlines are totally valid characters, like letters and digits. They are a part of the DOM.
Spaces and newlines before
<head>
are ignored for historical reasons.If we put something after
</body>
, then that is automatically moved inside the body, at the end, as the HTML spec requires that all content must be inside<body>
.
Autocorrection
If the browser encounters malformed HTML, it automatically corrects it when making the DOM.
The browser will add
<html>
,<head>
,<body>
if they don't exist.A document with unclosed tags will become a normal DOM as the browser reads tags and restores the missing parts.
Other node types
Everything in HTML, even comments, becomes a part of the DOM.
document
– the “entry point” into DOM.element nodes
– HTML-tags, the tree building blocks.text nodes
– contain text.comments
– sometimes we can put information there, it won’t be shown, but JS can read it from the DOM.
1.3 Walking the DOM
All operations on the DOM start with the document object. That’s the main “entry point” to DOM.
On top: documentElement and body
<html>
=document.documentElement
<body>
=document.body
<head>
=document.head
A script cannot access an element that doesn’t exist at the moment of running. If a script is inside <head>
, then document.body
is null
.
Children: childNodes, firstChild, lastChild
Child nodes (or children) – elements that are direct children.
Descendants – children, children of children, etc.
Properties firstChild
and lastChild
give fast access to the first and last children.
DOM collections
Dom collection is a special array-like iterable object.
We can use
for..of
to iterate over it. (Don't usefor...in
.)Array methods won’t work, because it’s not an array. (Use
Array.from
to convert)DOM collections are read-only and live.
Siblings and the parent
nextSibling
:<body>
is the “next” or “right” sibling of<head>
.previousSibling
:<head>
is the “previous” or “left” sibling of<body>
.
Element-only navigation
For many tasks we only want to manipulate element nodes that represent tags and form the structure of the page.
children
: only those children that are element nodes.firstElementChild
,lastElementChild
: first and last element children.previousElementSibling
,nextElementSibling
: neighbor elements.parentElement
: parent element.
parentElement
The root node document.documentElement
(<html>
) has document as its parent. But document
is not an element node, so parentNode
returns it and parentElement
does not.
More links: tables
table.rows
: the collection of<tr>
elements of the table.table.caption
/tHead
/tFoot
: references to elements<caption>
,<thead>
,<tfoot>
.table.tBodies
: the collection of<tbody>
elements.
, ,
tbody.rows
: the collection of<tr>
inside.tr.cells
: the collection of<td>
and<th>
cells inside the given<tr>
.tr.sectionRowIndex
: the position of the given<tr>
inside the enclosing<thead>
/<tbody>
/<tfoot>
.tr.rowIndex
: the number of the<tr>
in the table as a whole
and
td.cellIndex
: the number of the cell inside the enclosing<tr>
.
1.4 Searching: getElement, querySelector
document.getElementById or just id
If an element has the id
attribute, we can get the element using the method document.getElementById(id)
. There can be only one element in the document with the given id
.
It's also available as a global varaible, but it will be overwritten by varaibles declared in the script. Don’t use id-named global variables to access elements.
querySelectorAll
elem.querySelectorAll(css)
returns all elements inside elem matching the given CSS selector.
querySelector
elem.querySelector(css)
returns the first element for the given CSS selector.
matches
The elem.matches(css)
merely checks if elem
matches the given CSS-selector. It's useful when iterating over elements.
closest
elem.closest(css)
looks the nearest ancestor that matches the CSS-selector. The elem
itself is also included in the search.
getElementsBy*
elem.getElementsByTagName(tag)
looks for elements with the giventag
and returns the collection of them.elem.getElementsByClassName(className)
returns elements that have the given CSS class.document.getElementsByName(name)
returns elements with the givenname
attribute, document-wide.
These method returns a collection, not a single element.
All methods "getElementsBy*
" return a live collection. In contrast, querySelectorAll
returns a static collection. It’s like a fixed array of elements.
elemA.contains(elemB)
returns true if elemB
is inside elemA
or when elemA == elemB
.
1.5 Node properties: type, tag and contents
DOM node classes
Each DOM node belongs to the corresponding built-in class.
EventTarget
: the root “abstract” class. Objects of that class are never created. It serves as a base, so that all DOM nodes support so-called “events”.Node
: It provides the core tree functionality:parentNode
,nextSibling
,childNodes
and so on (they are getters).Text
for text nodes,Element
for element nodes and more exotic ones likeComment
for comment nodes.Element
: It provides element-level navigation likenextElementSibling
,children
and searching methods likegetElementsByTagName
,querySelector
.HTMLElement
– the basic class for all HTML elements.HTMLInputElement
: the class for<input>
elements.
HTMLBodyElement
: the class for<body>
elements.
HTMLAnchorElement
: the class for<a>
elements.
The “nodeType” property
elem.nodeType == 1
for element nodeselem.nodeType == 3
for text nodeselem.nodeType == 9
for the document object
Tag: nodeName and tagName
The
tagName
property exists only forElement
nodes.The
nodeName
is defined for anyNode
.
innerHTML: the contents
The innerHTML
property allows to get the HTML inside the element as a string.
innerHTML+=
does a full overwrite instead of an addition. As the content is rewritten from the scratch, all images and other resources will be reloaded.
outerHTML: full HTML of the element
The outerHTML
property contains the full HTML of the element.
Writing to outerHTML
does not change the element. Instead, it replaces it in the DOM.
For example, what happened in div.outerHTML=<p>A new element</p>
is:
div
was removed from the document.Another piece of HTML
<p>A new element</p>
was inserted in its place.div
still has its old value. The new HTML wasn’t saved to any variable.
nodeValue/data: text node content
For non-element nodes, nodeValue
and data
are used to get the content.
textContent: pure text
The textContent
provides access to the text inside the element. Writing to textContent
is much more useful, because it allows to write text the “safe way”.
1.6 Attributes and properties
DOM properties
DOM properties and methods behave just like those of regular JavaScript objects:
They can have any value.
They are case-sensitive.
HTML attributes
When the browser parses the HTML to create DOM objects for tags, it recognizes standard attributes and creates DOM properties from them.
To access all attributes:
elem.attributes
: A collection of objects that belong to a built-inAttr
class.elem.hasAttribute(name)
elem.getAttribute(name)
elem.setAttribute(name, value)
elem.removeAttribute(name)
HTML attributes have the following features:
Their name is case-insensitive (
id
is same asID
).Their values are always strings.
Property-attribute synchronization
When a standard attribute changes, the corresponding property is auto-updated, and vice versa.
input.value
synchronizes only from attribute to property, but not back.
DOM properties are typed
DOM properties are not always strings.
The style
attribute is a string, but the style
property is an object:
The href
DOM property is always a full URL, even if the attribute contains a relative URL or just a #hash
.
Non-standard attributes, dataset
All attributes starting with data-
are reserved for programmers’ use. They are available in the dataset
property.
Multiword attributes like data-order-state
become camel-cased: dataset.orderState
.
1.7 Modifying the document
Creating an element
document.createElement(tag)
document.createTextNode(text)
Creating the message
div.className = "alert";
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
Insertion methods
node.append(...nodes or strings)
– append nodes or strings at the end of node.node.prepend(...nodes or strings)
– insert nodes or strings at the beginning of node.node.before(...nodes or strings)
- insert nodes or strings before node.node.after(...nodes or strings)
- insert nodes or strings after node.node.replaceWith(...nodes or strings)
- replaces node with the given nodes or strings.
The text is inserted “as text”, not “as HTML”, with proper escaping of characters such as <
, >
.
insertAdjacentHTML/Text/Element
To insert an HTML string “as html”, with all tags and stuff working:
elem.insertAdjacentHTML(where, html)
beforebegin
afterbegin
beforeend
afterend
elem.insertAdjacentText(where, text)
elem.insertAdjacentElement(where, elem)
Node removal
To remove a node, there’s a method node.remove()
.
All insertion methods automatically remove the node from the old place.
Cloning nodes: cloneNode
elem.cloneNode(true)
creates a deep clone of the element with all attributes and subelements.elem.cloneNode(false)
creates a clone without child elements.
DocumentFragment
DocumentFragment
is a special DOM node that serves as a wrapper to pass around lists of nodes. When we insert it somewhere, then its content is inserted instead.
Old-school insert/remove methods
This information helps to understand old scripts.
parentElem.appendChild(node)
: Appendsnode
as the last child ofparentElem
.parentElem.insertBefore(node, nextSibling)
: Insertsnode
beforenextSibling
intoparentElem
.parentElem.replaceChild(node, oldChild)
:Replaces
oldChild
withnode
among children ofparentElem
.parentElem.removeChild(node)
: Removesnode
fromparentElem
.
A word about “document.write”
There’s one more, very ancient method of adding something to a web-page: document.write
. The method comes from times when there was no DOM, no standards.
The call to document.write
only works while the page is loading. If we call it afterwards, the existing document content is erased.
1.8 Styles and classes
className and classList
elem.className
elem.classList
add/remove
toggle
contains
Element style
Resetting the style property
elem.style.display = "none"
: Set a style property. elem.style.display = ""
: Reset a style property to default. elem.style.cssText
: Full rewrite the CSS string.
Computed styles: getComputedStyle
The style property operates only on the value of the style
attribute, without any CSS cascade.
getComputedStyle(element, [pseudo])
element
pseudo
: Example:::before
Visited links may be colored using :visited
CSS pseudoclass. getComputedStyle
can't access that color because of privacy concerns.
1.9 Element size and scrolling
offsetParent, offsetLeft/Top
The offsetParent
is the nearest ancestor that the browser uses for calculating coordinates during rendering.
Properties offsetLeft
/offsetTop
provide x/y coordinates relative to offsetParent upper-left corner.
offsetWidth/Height
They provide the “outer” width/height of the element or its full size including borders. Geometry properties are zero/null for elements that are not displayed.
clientTop/Left
clientLeft = 25
– left border widthclientTop = 25
– top border width
clientWidth/Height
They include the content width together with paddings, but without the scrollbar.
If there are no paddings, then clientWidth
/clientHeight
is exactly the content area, inside the borders and the scrollbar.
scrollWidth/Height
These properties are like clientWidth
/clientHeight
, but they also include the scrolled out parts.
scrollLeft/scrollTop
Properties scrollLeft
/scrollTop
are the width/height of the hidden, scrolled out part of the element.
Don’t take width/height from CSS
1.10 Window sizes and scrolling
Width/height of the window
document.documentElement.clientWidth
document.documentElement.clientHeight
They provide the width/height without the scrollbar.
In modern HTML we should always write DOCTYPE
. Without it, top-level geomtry properties may work a little bit different.
Width/height of the document
To reliably obtain the full document height:
Get the current scroll
Scrolling: scrollTo, scrollBy, scrollIntoView
To scroll the page from JavaScript, its DOM must be fully built.
Regular elements can be scrolled by changing scrollTop
/scrollLeft
.
For the whole window, use these methods:
scrollIntoView
The call to elem.scrollIntoView(top)
scrolls the page to make elem
visible.
top=true
: scroll to makeelem
appear on the top of the windowtop=false
: scroll to makeelem
appear at the bottom
Forbid the scrolling
The page will freeze on its current scroll.
If the scrollbar occupied some space, then that space is now free, and the content fill it.
1.11 Coordinates
Relative to the window (
clientX
/clientY
) (position:fixed
)Relative to the document (
pageX
/pageY
) (position:absolute
)
Element coordinates: getBoundingClientRect
The method elem.getBoundingClientRect()
returns window coordinates for a minimal rectangle that encloses elem
as an object of built-in DOMRect
class.
x/y
– X/Y-coordinates of the rectangle origin relative to window,width/height
– width/height of the rectangle (can be negative).top/bottom/left/right
Coordinates right
/bottom
are different from CSS position properties. In CSS positioning, right
property means the distance from the right edge, and bottom
property means the distance from the bottom edge.
elementFromPoint(x, y)
The call to document.elementFromPoint(x, y)
returns the most nested element at window coordinates (x, y)
. It only works if (x,y) are inside the visible area.
Document coordinates
pageY
=clientY
+ height of the scrolled-out vertical part of the document.pageX
=clientX
+ width of the scrolled-out horizontal part of the document.
Last updated