Exploring 5 Essential Observer Functions in JavaScript
Written on
Chapter 1: Introduction to Observers
Web browsers come equipped with powerful Observers that enhance the capabilities available to developers. This article delves into the primary Observers provided by browsers, examining their functions, applications, and best practices in web development.
MutationObserver
MutationObserver is a tool designed to observe alterations in DOM elements, including their child nodes. It triggers specific callbacks when attributes change or when nodes are added, removed, or modified.
To set up a MutationObserver, you first need a target DOM element to observe:
// Select the target DOM element for observation
const targetNode = document.getElementById("app");
// Configuration object to specify what mutations to observe
const config = {
attributes: true, // Monitor changes in attributes like id and class
childList: true, // Observe direct children of the target node
subtree: true, // Monitor all descendants, not just direct children
characterData: true // Include changes to text nodes
};
// Callback function that executes when mutations are detected
const callback = function (mutationsList, observer) {
console.log(mutationsList);
};
const observer = new MutationObserver(callback);
observer.observe(targetNode, config);
API Overview
- observe: This method initiates the monitoring process on the specified DOM node. A single MutationObserver can track multiple nodes by invoking observe multiple times.
- takeRecords: This method retrieves mutation records that are queued but not yet processed by the callback. It's useful when disconnecting the observer while preserving the mutation records.
Common Use Cases
MutationObserver is particularly useful for scenarios requiring dynamic updates to the DOM, such as creating a Todo List application.
<!-- Example of a simple Todo List -->
<ul id="todo-list">
<li>Complete homework</li>
<li>Shopping</li>
</ul>
<button id="addTask">Add task</button>
<button id="removeTask">Remove task</button>
<span id="taskCount">Number of tasks: 2</span>
const todoList = document.getElementById('todo-list');
const taskCount = document.getElementById('taskCount');
const observer = new MutationObserver((mutationsList) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
updateTaskCount();}
});
});
const config = { childList: true };
observer.observe(todoList, config);
document.getElementById('addTask').addEventListener('click', () => {
const newTask = document.createElement('li');
newTask.textContent = 'New task';
todoList.appendChild(newTask);
});
document.getElementById('removeTask').addEventListener('click', () => {
const tasks = todoList.getElementsByTagName('li');
if (tasks.length > 0) {
todoList.removeChild(tasks[0]);}
});
function updateTaskCount() {
const tasks = todoList.getElementsByTagName('li');
taskCount.textContent = Number of tasks: ${tasks.length};
}
IntersectionObserver
IntersectionObserver tracks the visibility of an element within a viewport, allowing developers to detect how much of an element is visible and trigger actions based on that visibility.
Basic Usage
const target = document.getElementById('app');
const options = {
root: null, // Observe visibility relative to the viewport
rootMargin: '0px', // Margin around the root
threshold: 0.5 // Trigger callback when at least 50% is visible
};
const intersectionObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
console.log(entry);});
}, options);
intersectionObserver.observe(target);
API Overview
- observe: This method starts observing the specified DOM element.
- entry: The first parameter in the callback represents an array of entry objects, detailing the visibility state of the observed element.
Practical Applications
Though it may seem limited at first glance, IntersectionObserver shines in scenarios like enhancing the user experience when a sticky header is in play.
const header = document.getElementById('sticky-header');
const options = { threshold: 1 };
const intersectionObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
header.classList.remove('shadow');} else {
header.classList.add('shadow');}
});
}, options);
intersectionObserver.observe(document.getElementById('guard'));
ResizeObserver
ResizeObserver is utilized for monitoring changes in the size of a DOM element. Whenever the size changes, a callback is triggered.
Basic Usage
const box = document.getElementById('box');
const resizeObserver = new ResizeObserver(entries => {
entries.forEach(entry => {
console.log(entry);});
});
resizeObserver.observe(box);
Common Use Cases
This observer can be employed to create a resize detector that provides size information when the dimensions of an element change.
<div id="resizable-box">Resize me!</div>
const resizableBox = document.getElementById('resizable-box');
const resizeObserver = new ResizeObserver(entries => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log('Width:', width, 'Height:', height);
}
});
resizeObserver.observe(resizableBox);
PerformanceObserver
PerformanceObserver serves to monitor performance-related events in the browser, allowing developers to react to various performance metrics.
Basic Usage
function perfObserver(list) {
console.log(list);
}
const observer2 = new PerformanceObserver(perfObserver);
observer2.observe({ entryTypes: ["measure"] });
Useful Entry Types
Common entry types include:
- mark: Marks events with timestamps.
- measure: Measures performance events.
- navigation: Tracks page load and reload events.
ReportingObserver
ReportingObserver listens for browser-reported events such as deprecated APIs and network issues, making it useful for developers maintaining SDKs.
Basic Usage
const observer = new ReportingObserver((reports) => {
reports.forEach(report => {
console.log(report);});
});
observer.observe({ types: ['deprecation'] });
The first video titled "Observer Pattern in JavaScript" covers key concepts and practical applications of observer patterns, providing a foundational understanding of how they operate.
The second video, "Learn Intersection Observer In 15 Minutes," offers a quick overview of the Intersection Observer API, demonstrating its functionalities and use cases in an engaging manner.