JavaScriptWindow & Document

window and document

Every browser page hands JavaScript two big global objects: window and document. Together they are your bridge from the language to the page. window represents the tab or frame your script is running in; document represents the HTML page loaded inside that window. Most of the browser APIs you will ever touch hang off one of these two objects.

window: the global object in browsers

In the browser, window is the global object. Any var or function declaration at the top level becomes a property of it, and built-ins like setTimeout, fetch and alert live on it too. You usually call them without the prefix because globals are implicit.

JS
console.log(window === globalThis); // true in browsers
console.log(window.setTimeout === setTimeout); // true

// All these are window properties:
window.alert("hi");
window.fetch("/api/me");
window.location.href; // current URL
Note
In modules (`<script type="module">`) and in strict mode, top-level `let`/`const`/`class` declarations are *not* added to `window` — only `var` and function declarations are. Modern code should not rely on that behaviour.
document: the page itself

document is the root of the DOM — the tree of nodes that represents the HTML page. From it you can query elements, read attributes, change text, listen for events and create new nodes.

JS
document.title;                          // <title> contents
document.documentElement;                // <html>
document.head;                           // <head>
document.body;                           // <body>
document.URL;                            // same as location.href

const heading = document.querySelector("h1");
heading.textContent = "Updated!";

const items = document.querySelectorAll("li");
items.forEach((li, i) => (li.dataset.index = i));
Key window properties you actually use
  • window.location — current URL, broken into parts; assign to it to navigate.

  • window.navigator — info about the browser, language, online state, clipboard, geolocation.

  • window.history — the session history of the tab; powers pushState/replaceState.

  • window.screen — physical screen size; useful only for very specific cases.

  • window.innerWidth / window.innerHeight — current viewport size in CSS pixels.

  • window.scrollX / window.scrollY — current scroll offsets.

  • window.localStorage / window.sessionStorage — small key/value stores.

  • window.console — the developer console.

location: where am I?

JS
const url = "https://example.com:8443/blog/post?id=42#comments";

// If location.href === url:
location.protocol; // "https:"
location.host;     // "example.com:8443"
location.hostname; // "example.com"
location.port;     // "8443"
location.pathname; // "/blog/post"
location.search;   // "?id=42"
location.hash;     // "#comments"

// Navigate:
location.href = "/login";          // full navigation
location.assign("/login");         // same as above
location.replace("/login");        // navigate without adding history entry
location.reload();                 // refresh

We cover URL parsing, building and URLSearchParams in detail on the Location API page.

navigator: about the browser

JS
navigator.language;     // "en-GB" — preferred UI language
navigator.languages;    // ["en-GB", "en", "fr"]
navigator.onLine;       // boolean (best-effort, not reliable for connectivity tests)
navigator.userAgent;    // long string — mostly *not* what you want
navigator.hardwareConcurrency; // logical CPU cores
navigator.maxTouchPoints;      // 0 on desktop, >0 on touch screens

// Feature objects (may be undefined on older browsers):
navigator.clipboard;    // writeText / readText
navigator.geolocation;  // getCurrentPosition / watchPosition
navigator.mediaDevices; // getUserMedia / enumerateDevices

Don't sniff userAgent to make decisions — feature-detect instead. See navigator for the long version.

history: the back/forward stack

JS
history.length;           // entries in this tab's history
history.back();           // same as the back button
history.forward();        // same as the forward button
history.go(-2);           // jump backward two entries

// SPAs use these to change the URL without navigating:
history.pushState({ page: "about" }, "", "/about");
history.replaceState({ page: "home" }, "", "/");

addEventListener("popstate", (e) => {
  console.log("URL changed:", location.pathname, e.state);
});

This is the foundation every client-side router (Next.js, React Router, Vue Router) is built on. See History API.

Common window events

JS
// Page is ready for scripts that need the DOM:
addEventListener("DOMContentLoaded", () => {
  console.log("HTML parsed, DOM ready");
});

// All resources (images, stylesheets) finished loading:
addEventListener("load", () => console.log("everything loaded"));

// User is about to leave — return a string to prompt them (some browsers ignore it):
addEventListener("beforeunload", (e) => {
  if (hasUnsavedWork) {
    e.preventDefault();
    e.returnValue = ""; // required for some browsers
  }
});

// Viewport size or orientation changed:
addEventListener("resize", () => console.log(innerWidth, innerHeight));

// Network status — best-effort:
addEventListener("online",  () => console.log("back online"));
addEventListener("offline", () => console.log("offline"));
HTML parsed, DOM ready
everything loaded
document.readyState

If your script runs after DOMContentLoaded has already fired, the event handler will never run. Check readyState and run immediately if needed.

JS
function whenReady(fn) {
  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", fn, { once: true });
  } else {
    fn();
  }
}

whenReady(() => {
  console.log("DOM is ready");
});
window vs document — quick mental model
  • window is the tab/frame: timers, network, storage, history, location, viewport.

  • document is the page inside it: HTML elements, text, attributes, events that bubble through the DOM.

  • Both exist only in browsers. In Node use globalThis instead of window; there is no document.

Tip
In DevTools you can type `window` or `document` and expand the tree to discover every API the browser exposes. It is the fastest reference there is.