Important Browser APIs Overview

Get a working, practical survey of the major browser APIs beyond the core DOM and Fetch — what each one is for, a minimal example of using it, and which ones require special permissions, HTTPS, or have browser-specific limits.

Beyond manipulating HTML and making network requests, browsers expose a large family of built-in APIs for reading the page's structure, watching for changes, talking to the operating system, and running code off the main thread. This lesson is a survey — a map of what exists and when to reach for each one — rather than an in-depth look at any single API.

DOM and Fetch (quick recap)

The DOM (Document Object Model) is the tree-shaped representation of a page that JavaScript can read and modify — document.querySelector, element.textContent, and element.addEventListener are the everyday DOM API surface covered in earlier lessons.

The Fetch API (fetch(url)) is the modern way to make HTTP requests from JavaScript, returning a Promise that resolves to a Response object. Both of these are foundational and assumed knowledge going into the rest of this overview.

URL and URLSearchParams

The URL object parses a URL string into its parts — protocol, host, pathname, search (query string), and hash — without you writing fragile string-splitting code. URLSearchParams, often accessed via url.searchParams, makes reading and building query strings straightforward.

No permissions or HTTPS are required; these are pure parsing/formatting utilities available everywhere.

• const url = new URL("https://example.com/search?q=arrays&page=2"); • url.searchParams.get("q") → "arrays" • url.searchParams.set("page", "3"); url.toString() reflects the change

Clipboard API

navigator.clipboard.writeText(text) and navigator.clipboard.readText() let a page copy to or read from the system clipboard. Because this touches something outside the page (the OS clipboard), it is gated behind two constraints: it requires a secure context (HTTPS, or localhost during development) and, for most actions, it must be triggered by a direct user gesture like a click — you cannot silently copy text in the background.

Geolocation API

navigator.geolocation.getCurrentPosition(successCallback, errorCallback) asks the browser for the user's physical location. This is one of the most tightly permissioned APIs available: it requires HTTPS, and the browser always shows an explicit permission prompt that the user can deny, meaning your error handler must always be ready to run.

IntersectionObserver, ResizeObserver, and MutationObserver

These three 'observer' APIs all watch something about the page and call your callback when it changes, without you having to poll or listen to expensive events like scroll yourself.

IntersectionObserver reports when an element enters or leaves the viewport (or another container) — the standard mechanism behind lazy-loading images and infinite-scroll. ResizeObserver reports when an element's size changes, which scroll and resize window events cannot do for individual elements. MutationObserver reports when the DOM tree itself changes (nodes added/removed, attributes changed), which is useful for reacting to content injected by other scripts.

• IntersectionObserver — 'is this element visible now?' • ResizeObserver — 'did this specific element's box size change?' • MutationObserver — 'did the DOM structure under here change?'

History API

The History API (history.pushState(), history.replaceState(), and the popstate event) lets JavaScript change the URL shown in the address bar and add entries to the browser's back/forward history without triggering a full page reload — the foundation of client-side routing in single-page applications.

Notifications API

Notification.requestPermission() followed by new Notification(title, options) shows an OS-level notification outside the browser window. This requires an explicit permission prompt (which the user can deny or later revoke) and generally requires a secure context; support and appearance also vary somewhat between browsers and operating systems.

Web Workers

A Web Worker (new Worker("script.js")) runs a separate JavaScript file on its own background thread, communicating with the main page via postMessage() and onmessage. This is the primary way to run CPU-heavy work (large computations, data processing) without freezing the page's UI, since workers do not have direct access to the DOM.

WebSocket

new WebSocket(url) opens a persistent, two-way connection between the browser and a server, unlike a Fetch request which is one request/one response and then closed. WebSockets are used for real-time features — chat apps, live dashboards, multiplayer updates — where the server needs to push data to the client at any time, not just in response to a request.

Canvas API

The <canvas> element combined with canvas.getContext("2d") (or a WebGL context) gives you a pixel-based drawing surface controlled entirely by JavaScript — shapes, images, text, and animation frames drawn imperatively, rather than through HTML elements and CSS. It's used for games, charts, image editors, and data visualizations that need direct pixel control.

Quick reference: minimal usage per API

Notice most of these are event-driven: you register a callback and the browser calls it when something happens, rather than you polling in a loop. wss:// (not ws://) is the encrypted WebSocket scheme, matching https:// for regular requests.

// URL / URLSearchParams
const url = new URL(location.href);
const page = url.searchParams.get("page");

// IntersectionObserver
const io = new IntersectionObserver((entries) => {
  entries.forEach(e => { if (e.isIntersecting) console.log("visible:", e.target); });
});
io.observe(document.querySelector("#target"));

// Web Worker
const worker = new Worker("worker.js");
worker.postMessage({ start: 1000000 });
worker.onmessage = (e) => console.log("result:", e.data);

// WebSocket
const socket = new WebSocket("wss://example.com/chat");
socket.onmessage = (event) => console.log("received:", event.data);
socket.onopen = () => socket.send("hello");

Code Examples

URL and URLSearchParams turn manual, error-prone string splitting/joining of query strings into simple method calls. Expected result: /courses cs https://example.com/courses?branch=cs&level=advanced url.searchParams.set("level", "advanced") both reads and rewrites a single query parameter safely.

This is a minimal lazy-loading implementation: images only load their real src when they actually scroll into view, saving bandwidth for images the user never sees. obs.unobserve(img) is important — without it, the observer keeps watching an image that has already been loaded and no longer needs attention.

entry.isIntersecting tells you whether that specific element is currently visible in the viewport.

This shows the defensive pattern real code needs around the Clipboard API: check that it exists (older browsers or insecure contexts may not expose it), and handle both success and failure since the user or browser can refuse the operation.

navigator.clipboard.writeText() returns a Promise, so success and failure are handled with .then()/.catch().

Common mistake: Calling navigator.clipboard.writeText() from inside a setTimeout callback (rather than directly from a click handler) often fails silently in some browsers, because it is no longer considered a direct response to a user gesture.

const url = new URL("https://example.com/courses?branch=cs&level=beginner");

console.log(url.pathname);                 // "/courses"
console.log(url.searchParams.get("branch")); // "cs"
url.searchParams.set("level", "advanced");
console.log(url.toString());
const images = document.querySelectorAll("img[data-src]");

const observer = new IntersectionObserver((entries, obs) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;      // load the real image
      obs.unobserve(img);             // stop watching this one
    }
  });
});

images.forEach((img) => observer.observe(img));
function copyShareLink(link) {
  if (!navigator.clipboard) {
    console.warn("Clipboard API not available (requires HTTPS/secure context).");
    return;
  }
  navigator.clipboard.writeText(link)
    .then(() => console.log("Copied to clipboard:", link))
    .catch((err) => console.error("Copy failed:", err));
}

// Typically called from a click handler:
// button.addEventListener("click", () => copyShareLink(window.location.href));

Permission and constraint map

Roughly: pure page/data APIs (URL, observers, Canvas, History) work anywhere; APIs that touch the OS or user privacy (Clipboard, Geolocation, Notifications) require HTTPS and often an explicit permission prompt the user can deny.

No special constraints         Secure context (HTTPS) usually required     Explicit permission prompt
---------------------          -----------------------------------------   ---------------------------
URL / URLSearchParams           Clipboard API                                Geolocation
MutationObserver                Geolocation                                  Notifications
ResizeObserver                  Notifications                                 
IntersectionObserver            Service Workers (related API)                
History API                     Clipboard (also gesture-gated)               
Canvas                                                                       
Web Workers (same-origin script)                                            
WebSocket (wss:// for encrypted)

Important Rules

Geolocation and Notifications always require explicit user permission via a browser prompt — code must handle the 'denied' case, not assume success.

Clipboard access and Geolocation both require a secure context (HTTPS or localhost) — they simply do not work on plain http:// pages.

Clipboard writes generally must be triggered directly by a user gesture (like a click), not from a delayed callback or background code.

Web Workers cannot touch the DOM directly — they communicate with the main thread only via postMessage()/onmessage.

Prefer IntersectionObserver/ResizeObserver over manual scroll/resize event listeners with polling — the observers are more efficient and built for exactly this purpose.

Where this shows up

Lazy-loaded images and infinite scroll feeds (IntersectionObserver), single-page app routing without full reloads (History API), 'Copy link' buttons (Clipboard API), store locators and delivery estimates (Geolocation), live chat and stock-ticker dashboards (WebSocket), and heavy client-side data crunching that shouldn't freeze the UI (Web Workers) are all everyday products of these APIs working together.

navigator.geolocation.getCurrentPosition(showPosition); // no error handler navigator.geolocation.getCurrentPosition(showPosition, handleError);

Omitting the error callback means a denied permission or unavailable location silently does nothing — always supply both success and error handlers for permission-gated APIs.

window.addEventListener("scroll", checkIfImageVisible); // runs constantly, expensive new IntersectionObserver(callback).observe(image); // fires only on actual visibility change

Manually checking element position on every scroll event is expensive and imprecise; IntersectionObserver is purpose-built and far more efficient for this exact task.

[Multiple Choice] Which API is the best fit for lazy-loading images only when they scroll into view? A. MutationObserver B. IntersectionObserver C. History API D. WebSocket

B. IntersectionObserver — IntersectionObserver is purpose-built to report when an element enters or leaves the viewport, making it the standard and most efficient choice for lazy-loading.

[True / False] The Geolocation and Clipboard APIs will work the same way on a plain http:// page as they do on https://. A. True B. False

B. False — False. Both APIs require a secure context — HTTPS (or localhost during development) — and are blocked or unavailable on plain, non-secure http:// pages.

Using URLSearchParams, write a function getQueryParam(name) that reads the current page's URL (window.location.search) and returns the value of the given query parameter, or null if it isn't present.

function getQueryParam(name) { const params = new URLSearchParams(window.location.search); return params.get(name); } // If the page URL is "...?course=js&level=intro": console.log(getQueryParam("course")); // "js" console.log(getQueryParam("missing")); // null new URLSearchParams(window.location.search) gives you a params object with a.get(name) method.