- Published on
Notes on Browser JavaScript
- Authors
- Name
- Rakesh Tembhurne
- @tembhurnerakesh
Browser: Document, Events, Interfaces
- Learning how to manage the browser page: Add elements, manipulate their size and position, dynamically create interfaces and interact with the visitor.
Document
- Browser Environment & Specs:
- Global Objects:
window
(global scope for browser APIs),document
(entry point to DOM). - Client-side JavaScript runs in a host environment (browser), providing objects like
window
,document
,navigator
,screen
,history
,location
. - Distinct from Node.js environment; different global objects and APIs.
- Global Objects:
- DOM Tree:
- Document Object Model (DOM): A programming interface for HTML/XML documents. Represents the page's structure as a tree of nodes.
- Nodes: Elements (tags), text nodes, comment nodes, document type node (
<!DOCTYPE html>
), document object itself. document
: The root of the DOM tree.
- Walking the DOM:
- Navigation properties (all nodes):
elem.childNodes
: LiveNodeList
of all direct children (including text/comment nodes).elem.firstChild
,elem.lastChild
: First/last child node.elem.parentNode
: Parent node.elem.nextSibling
,elem.previousSibling
: Next/previous sibling node.
- Element-only navigation properties (recommended for most HTML tasks):
elem.children
: LiveHTMLCollection
of direct element children.elem.firstElementChild
,elem.lastElementChild
: First/last element child.elem.parentElement
: Parent element (same asparentNode
for element nodes).elem.nextElementSibling
,elem.previousElementSibling
: Next/previous element sibling.
- Navigation properties (all nodes):
- Searching:
getElement*
,querySelector*
:document.getElementById('id')
: Returns single element, very fast.document.getElementsByName('name')
: LiveNodeList
byname
attribute.document.getElementsByTagName('tag')
: LiveHTMLCollection
by tag name.document.getElementsByClassName('class')
: LiveHTMLCollection
by class name.elem.querySelector('css-selector')
: Returns the first matching element, supports complex CSS selectors.elem.querySelectorAll('css-selector')
: Returns a staticNodeList
of all matching elements. More flexible but potentially slower for simple lookups.- Live vs. Static Collections:
getElementsBy*
methods return live collections (reflect DOM changes automatically).querySelectorAll
returns staticNodeList
(snapshot at time of call).
- Node Properties: Type, Tag & Contents:
nodeType
: Numeric constant (e.g.,Node.ELEMENT_NODE
(1),Node.TEXT_NODE
(3),Node.COMMENT_NODE
(8),Node.DOCUMENT_NODE
(9)).nodeName
/tagName
: Tag name (uppercase for elements, e.g., "DIV"),nodeName
for non-elements (e.g., "#text", "#comment", "#document").textContent
: Gets/sets only the text content of the element and all its descendants, stripping HTML tags. Safe from XSS.innerHTML
: Gets/sets the HTML content inside the element. Can include HTML tags. Vulnerable to XSS if used with untrusted data.outerHTML
: The full HTML of the element itself, including its outer tag.
- Attributes and Properties:
- HTML Attributes: Reflect attributes in HTML source. Accessed via:
elem.hasAttribute(name)
elem.getAttribute(name)
elem.setAttribute(name, value)
elem.removeAttribute(name)
- DOM Properties: JavaScript object properties on the DOM node. Directly accessed as
elem.propName
. - Synchronization: Many HTML attributes have corresponding DOM properties (e.g.,
id
,value
,href
). Changes to one usually reflect in the other, but not always (input.value
vsinput.getAttribute('value')
). data-*
attributes: Custom attributes stored indataset
DOM property (e.g.,<div data-key="value">
becomeselem.dataset.key
).
- HTML Attributes: Reflect attributes in HTML source. Accessed via:
- Modifying the Document:
document.createElement(tagName)
: Creates a new element node.document.createTextNode(text)
: Creates a new text node.node.append(...nodes or strings)
: Appends nodes/strings to the end ofnode
.node.prepend(...nodes or strings)
: Prepends nodes/strings to the beginning ofnode
.node.before(...nodes or strings)
: Inserts nodes/strings beforenode
.node.after(...nodes or strings)
: Inserts nodes/strings afternode
.node.replaceWith(...nodes or strings)
: Replacesnode
with new nodes/strings.node.remove()
: Removesnode
from its parent.parent.insertBefore(newElem, referenceElem)
: InsertsnewElem
beforereferenceElem
(older method).parent.appendChild(newElem)
: AppendsnewElem
toparent
(older method).elem.cloneNode(true/false)
: Clones element.true
for deep clone (with children),false
for shallow.elem.insertAdjacentHTML(position, htmlString)
: Inserts HTML string at specified position ('beforebegin'
,'afterbegin'
,'beforeend'
,'afterend'
). Useful for fast HTML insertion without DOM node creation overhead.
- Styles and Classes:
elem.style.prop
: Gets/sets inline CSS properties (e.g.,elem.style.backgroundColor = 'red'
). Overwrites any existing inline style.elem.style.cssText
: Gets/sets all inline styles as a string.getComputedStyle(elem, [pseudoElement])
: Returns an object containing the computed values of all CSS properties of an element. Read-only. Accounts for stylesheets, inherited styles, etc.elem.className
: Gets/sets the entireclass
attribute string. Overwrites existing classes.elem.classList
: Provides methods to manage classes (preferred):elem.classList.add('class')
elem.classList.remove('class')
elem.classList.toggle('class')
elem.classList.contains('class')
- Element Size and Scrolling:
elem.offsetWidth
/offsetHeight
: Geometric width/height of the element, including padding, border, and scrollbar (if visible).elem.clientWidth
/clientHeight
: Inner width/height, including padding but excluding border and scrollbar. Represents the content area.elem.scrollWidth
/scrollHeight
: The full scrollable width/height of the element's content, including non-visible parts.elem.scrollLeft
/scrollTop
: Gets/sets the horizontal/vertical scroll position of the element.
- Window Sizes and Scrolling:
window.innerWidth
/innerHeight
: Viewport width/height, including scrollbar.document.documentElement.clientWidth
/clientHeight
: Viewport width/height, excluding scrollbar. Often preferred for content area.window.scrollX
/scrollY
(orwindow.pageXOffset
/pageYOffset
): Current scroll position of the document from the top-left corner.window.scrollTo(x, y)
/window.scrollBy(x, y)
: Programmatically scrolls the window.
- Coordinates:
elem.getBoundingClientRect()
: Returns aDOMRect
object withleft
,top
,right
,bottom
,width
,height
properties, representing the element's size and its position relative to the viewport.document.documentElement.clientTop
/clientLeft
: Width of the top/left border of thedocument.documentElement
(usually 0 unless CSS changes it).elem.offsetParent
: The nearest positioned ancestor element.elem.offsetTop
/offsetLeft
: Position ofelem
relative to the top-left corner ofoffsetParent
.
Introduction to Events
- Introduction to Browser Events:
- Actions or occurrences recognized by the browser, e.g., mouse clicks, key presses, page loads.
- Event handlers/listeners: Functions executed when an event occurs. Registered using
elem.addEventListener(event, handler, [options])
. event
object: Passed to the handler, contains information about the event (type
,target
, coordinates, etc.).
- Bubbling and Capturing:
- Event Flow: When an event occurs on an element, it propagates through three phases:
- Capturing Phase: Event travels down from
window
to theevent.target
. Handlers registered withuseCapture = true
(orcapture: true
option) trigger here. - Target Phase: Event reaches the
event.target
element. - Bubbling Phase: Event travels up from
event.target
towindow
. Most common phase, default foraddEventListener
.
- Capturing Phase: Event travels down from
event.target
: The actual element where the event originated.event.currentTarget
: The element on which the event listener is currently being executed.event.stopPropagation()
: Prevents bubbling (and capturing) beyond the current element.event.stopImmediatePropagation()
: Prevents bubbling and prevents other handlers on the same element from executing.
- Event Flow: When an event occurs on an element, it propagates through three phases:
- Event Delegation:
- Attaching a single event listener to a parent element instead of multiple children.
- Relies on event bubbling: The event bubbles up from the actual
event.target
to the parent. - The handler then uses
event.target
to identify which child originated the event and acts accordingly. - Benefits:
- Performance: Fewer event listeners improve memory and performance.
- Dynamic Elements: Works automatically for elements added/removed after the initial setup.
- Cleaner Code: Centralizes event handling logic.
- Browser Default Actions:
- Many browser events have default actions (e.g., clicking a link navigates, submitting a form reloads).
event.preventDefault()
: Stops the default browser action for an event.return false
: An older way to prevent default action for handlers assigned viaon<event>
HTML attributes or DOM properties (e.g.,elem.onclick = function() { return false; }
). Not applicable foraddEventListener
.
- Dispatching Custom Events:
new Event(name, [options])
: Creates a generic custom event. Options includebubbles: true/false
,cancelable: true/false
.new CustomEvent(name, { detail: data, ...options })
: Creates a custom event with adetail
property for carrying arbitrary data.elem.dispatchEvent(event)
: Dispatches the created event on the specified element. The event then propagates as per bubbling/capturing rules.
UI Events
- Mouse Events:
click
: Fired onmousedown
followed bymouseup
on the same element.dblclick
: Fired on twoclick
events in rapid succession.mousedown
,mouseup
: Fired when a mouse button is pressed/released.mousemove
: Fired when the mouse pointer moves over an element.contextmenu
: Fired when the right mouse button is clicked (or equivalent action) on an element.event.clientX
/clientY
: Mouse coordinates relative to the viewport.event.pageX
/pageY
: Mouse coordinates relative to the document.event.button
: Which mouse button was pressed (0: left, 1: middle, 2: right).
- Moving the Mouse:
mouseover
/out
,mouseenter
/leave
:mouseover
: Fired when the mouse pointer enters an element or any of its descendants. Bubbles.mouseout
: Fired when the mouse pointer leaves an element or moves into one of its descendants. Bubbles.mouseenter
: Fired when the mouse pointer enters an element. Does not bubble. Only fires for the element itself, not its descendants.mouseleave
: Fired when the mouse pointer leaves an element. Does not bubble.event.relatedTarget
: The element that the mouse pointer entered from (mouseout
,mouseleave
) or exited to (mouseover
,mouseenter
). Crucial for managing transitions between elements.
- Drag'n'Drop with Mouse Events:
- Implemented by combining
mousedown
(start drag),mousemove
(track drag), andmouseup
(end drag). - Requires preventing default browser text selection or image dragging.
- Can involve modifying CSS (e.g.,
position: absolute
) andz-index
for the dragged element.
- Implemented by combining
- Pointer Events:
- A unified event model for all input pointer devices (mouse, pen, touch).
- Provides consistent events across different input types.
- Events:
pointerdown
,pointermove
,pointerup
,pointercancel
,pointerover
,pointerout
,pointerenter
,pointerleave
,gotpointercapture
,lostpointercapture
. event.pointerId
: Unique ID for the pointer (e.g., specific finger or mouse).event.isPrimary
:true
if this is the primary pointer for a multitouch/multi-input interaction.elem.setPointerCapture(pointerId)
: Designateselem
to receive all subsequent pointer events forpointerId
, regardless of pointer position.elem.releasePointerCapture(pointerId)
: Releases pointer capture.
- Keyboard:
keydown
andkeyup
:keydown
: Fired when a key is pressed. Fires repeatedly if held down (event.repeat
).keyup
: Fired when a key is released.event.key
: Represents the character value of the key (e.g., "A", "Enter", "F5", "ArrowLeft").event.code
: Represents the physical key code (e.g., "KeyA", "Enter", "F5", "ArrowLeft"). Stable across keyboard layouts.- Modifier keys:
event.ctrlKey
,event.shiftKey
,event.altKey
,event.metaKey
(Command
on Mac,Windows
key on Windows).
- Scrolling:
scroll
event: Fired when an element or the document view is scrolled.- Often triggers frequently, so throttling or debouncing handlers is crucial for performance.
- Can check
document.documentElement.scrollTop
/scrollLeft
(for document) orelem.scrollTop
/scrollLeft
(for specific elements).
Forms, Controls
- Form Properties and Methods:
form.elements
: A collection (NodeList) of all form controls (input, textarea, select, button).form.elements.name
: Access control by itsname
attribute.form.submit()
: Programmatically submits the form. Does not trigger thesubmit
event.form.reset()
: Resets all form fields to their initial values. Does not trigger thereset
event.
- Focusing:
focus
/blur
:focus
: Fired when an element receives focus (e.g., via click, tab,elem.focus()
). Does not bubble.blur
: Fired when an element loses focus. Does not bubble.- For bubbling behavior, use
focusin
(bubbles when element gains focus) andfocusout
(bubbles when element loses focus). elem.focus()
: Programmatically sets focus to an element.elem.blur()
: Programmatically removes focus from an element.document.activeElement
: Returns the currently focused element in the document.
- Events:
change
,input
,cut
,copy
,paste
:change
: Fired when an element's value is committed.- For
input type="text"
,textarea
,select
: Fired when value changes and element loses focus (blurs). - For
input type="checkbox"
,radio
: Fired immediately when checked/unchecked.
- For
input
: Fired immediately when the value of aninput
ortextarea
element is changed by the user (e.g., on every keystroke).cut
,copy
,paste
: Fired when text is cut, copied, or pasted.event.clipboardData
object provides access to clipboard data.
- Forms:
event
andmethod submit
:submit
event: Fired on the<form>
element when the form is submitted (e.g., by clickingtype="submit"
button, pressing Enter in an input field). Can be prevented usingevent.preventDefault()
to handle submission via AJAX.form.submit()
method: See above (Form Properties and Methods
). It's a method call, not an event dispatch.
Document and Resource Loading
- Page:
DOMContentLoaded
,load
,beforeunload
,unload
:DOMContentLoaded
: Fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. The DOM is ready for interaction.load
: Fired when the entire page, including all dependent resources (images, stylesheets, scripts, etc.), has been fully loaded.beforeunload
: Fired when the user is about to navigate away from the page (e.g., closing tab, clicking link, submitting form). Allows preventing navigation with a confirmation dialog (browser-specific).unload
: Fired when the document is being unloaded. Limited reliability and functionality due to browsers restricting operations to prevent issues. Only very basic, non-blocking operations are possible.
- Scripts:
async
,defer
:<script>
(no attributes): Parser blocks, script downloads, executes, then parser resumes. Blocking.<script async>
: Downloads asynchronously, executes as soon as downloaded (regardless of HTML parsing completion or other script order). Non-blocking, order not guaranteed. Use for independent scripts.<script defer>
: Downloads asynchronously, executes after HTML parsing is complete (just beforeDOMContentLoaded
), maintains relative order with otherdefer
scripts. Non-blocking, order guaranteed fordefer
scripts. Ideal for most scripts that interact with the DOM.
- Resource Loading:
onload
andonerror
:- Events for individual resources (
<img>
,<script>
,<link>
,<iframe>
). resource.onload
: Fired when the resource has successfully loaded.resource.onerror
: Fired when an error occurs during resource loading.
- Events for individual resources (
Miscellaneous
- Mutation Observer:
- An API to observe changes made to the DOM tree. Provides a way to react to modifications.
new MutationObserver(callback)
: Creates an observer instance. Thecallback
receives a list ofMutationRecord
objects describing the changes.observer.observe(targetNode, options)
: Configures the observer to watchtargetNode
for specified types of changes.options
: Object specifying what to observe (e.g.,childList: true
,attributes: true
,subtree: true
,characterData: true
).
observer.disconnect()
: Stops the observer from receiving further notifications.observer.takeRecords()
: Returns any pendingMutationRecord
objects and empties the observer's record queue.- Use Cases: Reacting to dynamic content loading, implementing virtual DOM, monitoring third-party script changes.
- Selection and Range:
- Selection: Represents the user's current text selection.
window.getSelection()
: Returns aSelection
object.- Properties:
anchorNode
,anchorOffset
(start of selection),focusNode
,focusOffset
(end of selection),isCollapsed
(true if no text is selected). - Methods:
addRange()
,removeRange()
,removeAllRanges()
,toString()
(gets selected text).
- Range: A contiguous portion of the DOM tree. Can represent a selection, but also arbitrary parts of the document.
document.createRange()
: Creates an emptyRange
object.- Methods:
range.setStart(node, offset)
,range.setEnd(node, offset)
: Define range boundaries.range.selectNode(node)
,range.selectNodeContents(node)
: Select entire nodes or their contents.range.deleteContents()
: Removes content within the range.range.extractContents()
: Removes content and returns it as aDocumentFragment
.range.surroundContents(newParentNode)
: Wraps the range's content withnewParentNode
.
- Use Cases: Implementing rich text editors, custom text highlighting, manipulating specific document fragments.
- Selection: Represents the user's current text selection.
Event Loop: Microtasks and Macrotasks
- Event Loop: The fundamental concurrency model in JavaScript (and browsers/Node.js). It continuously checks the call stack, macrotask queue, and microtask queue to decide what code to execute next.
- Ensures non-blocking I/O operations by offloading tasks and executing their callbacks later.
- A single-threaded model, but gives the illusion of concurrency.
- Macrotasks (Tasks):
- Represent a "big" unit of work. Only one macrotask is processed per turn of the event loop.
- After a macrotask completes, the browser renders (if needed) and then the event loop processes all available microtasks.
- Common Sources:
setTimeout()
setInterval()
- UI rendering events (e.g.,
requestAnimationFrame
is often associated with rendering) - I/O operations (e.g., network requests like
fetch
response,XMLHttpRequest
) - Script execution (the main script itself is an initial macrotask)
MessageChannel
callbacks
- Microtasks (Jobs):
- Represent a "small" unit of work. The microtask queue is processed completely after the current macrotask finishes and before the next macrotask starts (or before rendering).
- If a microtask adds new microtasks, those new microtasks are also processed in the same microtask queue turn. This can lead to "microtask starvation" if not managed carefully.
- Common Sources:
Promise
callbacks (.then()
,.catch()
,.finally()
)await
callbacks (resume after promise resolves)queueMicrotask()
MutationObserver
callbacks
- Processing Order (Simplified Cycle):
- Execute one macrotask from the macrotask queue (or initial script).
- After the macrotask finishes, process all microtasks in the microtask queue.
- If microtasks add more microtasks, process them immediately until the microtask queue is empty.
- Perform browser rendering updates (if any changes were made and time allows).
- Repeat the cycle, taking the next macrotask.
- Key Takeaway: Microtasks have higher priority than macrotasks. They run immediately after the currently executing script/macrotask, before the browser gets a chance to render or run another macrotask.
Related Posts
Notes on Advanced JavaScript
JavaScript is a dynamic and interactive programming language that runs in web browsers and other software applications that use the JavaScript engine.
Notes on JavaScript
Notes on JavaScript, a versatile programming language widely used for web development.