The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Use the Screen Capture API. In the button’s click handler, call navigator.mediaDevices.getDisplayMedia(), let the user choose a window or tab, grab one video frame, draw it to a canvas, and download the canvas as a PNG. A web page cannot silently capture an arbitrary browser window: the browser picker and a user approval are required for every capture.
This guide covers complete-window, tab, monitor, and DOM-element cases, with cancellation handling, cleanup, browser-support limitations, and an API alternative when you do not want to manage browser capture.
What “browser window screenshot” can mean
Choose the capture scope before writing code:
- Window: a selected application or browser window.
- Tab: one browser tab, as offered by the browser picker.
- Monitor: an entire display, including everything visible on it.
- DOM element: a specific rendered element inside your page. This uses Element Capture or Region Capture and has additional support requirements.
For a normal window or tab screenshot, use display capture and allow the user to make the selection. The displaySurface constraint can express a preference, but it cannot bypass or restrict the browser’s chooser.
Complete button-click implementation
The following page requests capture only after a click, takes one frame, downloads screenshot.png, reports failures, and stops every track when finished.
#1 Best Overall
- Compact Mouse: With a comfortable and contoured shape, this Logitech ambidextrous wireless mouse feels great in either right or left hand and is far superior to a touchpad
- Durable and Reliable: This USB wireless mouse features a line-by-line scroll wheel, up to 1 year of battery life (2) thanks to a smart sleep mode function, and comes with the included AA battery
- Universal Compatibility: Your Logitech mouse works with your Windows PC, Mac, or laptop, so no matter what type of computer you own today or buy tomorrow your mouse will be compatible
- Plug and Play Simplicity: Just plug in the tiny nano USB receiver and start working in seconds with a strong, reliable connection to your wireless computer mouse up to 33 feet / 10 m (5)
- Better than touchpad: Get more done by adding M185 to your laptop; according to a recent study, laptop users who chose this mouse over a touchpad were 50% more productive (3) and worked 30% faster (4)
<button id="capture" type="button">Capture screenshot</button>
<p id="status" role="status"></p>
<a id="download" hidden>Download screenshot</a>
<script>
const button = document.querySelector("#capture");
const status = document.querySelector("#status");
const downloadLink = document.querySelector("#download");
let previousUrl;
button.addEventListener("click", async () => {
button.disabled = true;
status.textContent = "Choose a window or tab in the browser dialog.";
let stream;
let bitmap;
try {
// Keep this call directly inside the user-activation handler.
stream = await navigator.mediaDevices.getDisplayMedia({
video: { displaySurface: "window" },
audio: false
});
const [track] = stream.getVideoTracks();
if (!track) throw new Error("No video track was returned.");
const imageCapture = new ImageCapture(track);
bitmap = await imageCapture.grabFrame();
const canvas = document.createElement("canvas");
canvas.width = bitmap.width;
canvas.height = bitmap.height;
const context = canvas.getContext("2d");
if (!context) throw new Error("Canvas 2D context is unavailable.");
context.drawImage(bitmap, 0, 0);
const blob = await new Promise(resolve => {
canvas.toBlob(resolve, "image/png");
});
if (!blob) throw new Error("The browser could not encode the image.");
if (previousUrl) URL.revokeObjectURL(previousUrl);
previousUrl = URL.createObjectURL(blob);
downloadLink.href = previousUrl;
downloadLink.download = "screenshot.png";
downloadLink.hidden = false;
downloadLink.click();
status.textContent = "Screenshot saved.";
} catch (error) {
console.error("Screenshot capture failed:", error);
if (error.name === "NotAllowedError") {
status.textContent = "Capture was cancelled or permission was denied.";
} else {
status.textContent = `Screenshot failed: ${error.message || error.name}`;
}
} finally {
stream?.getTracks().forEach(track => track.stop());
bitmap?.close();
button.disabled = false;
}
});
</script>
getDisplayMedia() returns a MediaStream, not an image file. ImageCapture.grabFrame() extracts one frame into an ImageBitmap; the canvas then encodes that bitmap as a PNG Blob. The object URL is suitable for a download link and should be revoked before replacing it.
Why the call must be inside the click handler
Screen capture requires transient user activation. Calling it from page load, a timer, or a promise chain that has lost the click activation can reject before the picker appears. The browser must also prompt the user each time; a previous approval is not a reusable permission grant. Keep the API call as the first asynchronous operation in the event handler.
Choosing a window, tab, or monitor
The browser owns the picker. The user selects a source and approves sharing, so JavaScript cannot name an arbitrary operating-system window or suppress the chooser. The example’s displaySurface: "window" preference asks for a window-oriented selection where supported, but the final surface remains the user’s choice.
To avoid steering the chooser, remove the preference:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: false
});
Audio is disabled because a still image does not need it. If you do request audio for another use case, treat that as a separate privacy decision and do not assume every surface supplies an audio track.
Rank #2
- Pair and Play: With fast, easy Bluetooth wireless technology, you’re connected in seconds to this quiet cordless mouse —no dongle or port required
- Less Noise, More Focus: Silent mouse with 90% reduced click sound and the same click feel, eliminating noise and distractions for you and others around you (1)
- Long-Lasting Battery Life: Up to 18-month battery life with an energy-efficient auto sleep feature, so you can go longer between battery changes (2)
- Comfortable, Travel-Friendly Design: Small enough to toss in a bag; this slim and ambidextrous portable compact mouse guides either your right or left hand into a natural position
- Long-Range: Reliable, long-range Bluetooth wireless mouse works up to 10m/33 feet away from your computer (3)
Saving, previewing, and selecting an image format
Download a PNG
PNG is lossless and preserves text well. The sample uses canvas.toBlob(resolve, "image/png") and sets the download filename.
Show a preview first
Instead of clicking the link immediately, put the Blob URL on an image:
const preview = document.querySelector("#preview");
preview.src = previousUrl;
preview.hidden = false;
Let the user confirm the frame, then click the download link. Keep only one active URL and call URL.revokeObjectURL() when replacing or removing it.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteUse JPEG or WebP
For photographs or smaller files, change the MIME type and filename:
const blob = await new Promise(resolve =>
canvas.toBlob(resolve, "image/jpeg", 0.9)
);
downloadLink.download = "screenshot.jpg";
JPEG quality is a number from 0 to 1 and is lossy. WebP support is broad in modern browsers, but test the browsers that your application promises to support.
Rank #3
- 【Dual Mode Wireless Bluetooth Mouse】: Switch easily between two devices—connect one via Bluetooth (BT5.2/3.0) and the other using a 2.4G USB receiver. No drivers needed; just plug and play. Enjoy a reliable connection up to 33 feet. Note: You can't use both modes simultaneously; the USB receiver is stored in the mouse.
- 【Rechargeable Wireless Mouse】: Equipped with a 500mAh lithium-ion battery, it charges in 2 hours for over 7 days of use and 30 days on standby. The mouse sleeps after 5 minutes of inactivity to save power and can be woken with any click.
- 【Colorful LED Breathing Light】: Features 7 colorful LED lights that change randomly, adding a fun atmosphere to your workspace.
- 【Portable Mouse】Compact size (4.4 x 2.3 x 1.1 inches) makes it easy to fit in your laptop bag. Lightweight and ergonomic, it's perfect for travel. Contact us anytime for support.
- 【Wide Compatibility】: Works with laptops, PCs, tablets, and smartphones across various operating systems, including Android, Windows, and Mac. Ideal for home, office, and travel.
Capturing a specific DOM element
Regular display capture captures a surface selected in the browser dialog; it does not accept a CSS selector for an arbitrary element. If the target is content in your own page, consider Element Capture and Region Capture. Element Capture can restrict a captured stream to an element and its descendants, while Region Capture crops to an element’s screen region. Both build on display capture and have their own browser-support requirements.
When those APIs are unavailable or unnecessary, a practical fallback is to ask the user to select the tab containing the element and capture the visible tab. Do not describe that as element-only capture: surrounding tab content can remain in the frame.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteSecurity, privacy, and embedding requirements
- Explain the scope: a chosen window may expose passwords, messages, customer data, or other visible information.
- Stop promptly: calling
stop()on every track ends active sharing and removes the page’s capture state. - Use a secure context: deploy over HTTPS (localhost is generally treated as secure for development).
- Check iframe policy: an embedding page may need a Permissions Policy that allows
display-capture. A restrictive policy can prevent the iframe from using the API. - Watch indicators: browsers display sharing indicators and may provide a stop-sharing control outside your page.
See MDN’s Screen Capture API usage guide for stream handling, indicators, and policy details.
Browser support and feature detection
MDN marks getDisplayMedia() as having limited availability, and ImageCapture.grabFrame(), Element Capture, and Region Capture have separate support requirements. Check the live compatibility data for every browser and operating system in your support matrix before shipping.
const canCapture =
!!navigator.mediaDevices?.getDisplayMedia;
const canGrabFrame = "ImageCapture" in window;
if (!canCapture || !canGrabFrame) {
// Offer an explanation or an alternative workflow.
}
Feature detection prevents a misleading button in unsupported browsers, but it cannot guarantee that the operating system will provide a capturable source. Keep the rejection handler for runtime failures.
Rank #4
- Your hand can relax in comfort hour after hour with this ergonomically designed mouse. Its contoured shape with soft rubber grips, gently curved sides and broad palm area give you the support you need for effortless control all day long.
- You’ve got the control to do more, faster. Flipping through photo albums and Web pages is a breeze, especially for right-handers—with three standard buttons plus Back/Forward buttons that you can also program to switch applications, go full screen and more. And side-to-side scrolling plus zoom gives you the power to scroll horizontally and vertically through your music library, maps and Facebook feeds, and zoom in and out of photos and budget spreadsheets with a click.* * Requires Logitech SetPoint software (Windows) or Logitech Control Center software (Mac OS X)
- Two years of battery life practically eliminates the need to replace batteries. ** The On/Off switch helps conserve power, smart sleep mode extends battery life and an indicator light eliminates surprises. ** Battery life may vary based on user and computing conditions.
- The tiny Logitech Unifying receiver stays in your laptop. There’s no need to unplug it when you move around, so there’s less worry of it being lost. And you can easily add compatible wireless mice and keyboards to the same wireless receiver.
Troubleshooting common failures
No picker appears
Ensure the call happens directly in a click or keyboard-activation handler, use HTTPS, and verify that the document is focused and active. Calls made after a timeout commonly lose transient activation.
The user cancelled or denied access
This normally produces NotAllowedError. Leave the page usable, tell the user that no image was created, and allow another click. Do not repeatedly reopen the picker without a new user action.
“No sources” or an operating-system error
A source may be unavailable, the browser may be running in a restricted environment, or the OS may block capture. Try another tab or window, check system privacy settings, and test outside remote-desktop or kiosk restrictions.
The image is blank or stale
Wait for the track to become live before grabbing a frame:
const [track] = stream.getVideoTracks();
if (track.readyState !== "live") {
await new Promise(resolve => {
const timer = setInterval(() => {
if (track.readyState === "live") {
clearInterval(timer);
resolve();
}
}, 25);
});
}
Also confirm that the selected surface is not minimized or hidden by the operating system. Capture one frame only after the picker has returned a live track.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
- 【Plug and Play for Home/Office/School】The wireless computer mouse features 2.4GHz connectivity, delivering a stable, interference-free connection up to 32ft. Designed for 𝐦𝐞𝐝𝐢𝐮𝐦 𝐭𝐨 𝐥𝐚𝐫𝐠𝐞 𝐬𝐢𝐳𝐞𝐝 𝐡𝐚𝐧𝐝𝐬, it ensures comfortable use all day. Simply plug in the USB-A receiver for instant pairing—no drivers needed. 📌📌 If the mouse isn’t suitable, place the USB receiver in the battery compartment and return both.
- 【3 Levels Adjustable DPI】This travel USB mouse offers 3 adjustable DPI settings (800, 1200, 1600), allowing you to customize sensitivity for precise design work. Effortlessly switch to match your task and elevate your productivity. 📌 Please remove the film at the bottom of the mouse before use.
- 【Effortless Browsing】Equipped with forward and backward buttons, this computer mice streamlines your workflow, making it easy to navigate through web pages and files with a simple click. 📌Side button does not work on Mac.
- 【Visible Indicator Light】 The pc mouse features a visual indicator for DPI levels and low battery alerts. The red light flashes once for 800 DPI, twice for 1200 DPI, and three times for 1600 DPI. When the battery level is below 10%, the light flashes red until the mouse is completely out of power.
- 【Click to Wake】With smart sleep mode, it saves power by standby after 10 inactive minutes, just 2-3 clicks to wake. This efficient design delivers 3x longer battery life than motion-wake mice. Engineered for durability, its buttons and scroll wheel are tested for 10 million clicks, ensuring long-term reliability and consistent performance.
ImageCapture is unavailable
Use a hidden video element as a compatibility fallback. Assign video.srcObject = stream, wait for loadedmetadata, draw the video to a canvas with drawImage(video, 0, 0), then stop the tracks. Test this path carefully because frame timing differs between browsers.
The iframe cannot capture
Inspect the top-level Permissions Policy and the iframe’s allow attribute. A policy must permit display-capture for the document that calls the API.
Performance and reliability choices
- Capture one frame rather than recording a stream when the requirement is a still image.
- Large monitor captures create large canvases and Blobs. Consider resizing the canvas before encoding if your application only needs a thumbnail.
- Disable the button during the asynchronous operation to prevent overlapping pickers and leaked streams.
- Always clean up in
finally, including error and cancellation paths. - Use PNG for crisp interfaces and JPEG/WebP when file size matters more than lossless text.
- Do not assume a particular pixel density. Retina or scaled displays can produce dimensions different from CSS pixels; use
bitmap.widthandbitmap.heightrather than viewport values.
Or skip the browser setup
If your application needs server-side screenshots, scheduled captures, bulk URLs, or a workflow that should not open a user-facing picker, ScreenshotNeo provides a website screenshot API and MCP server. It removes cookie-consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, with the result identified by X-Page-Verdict and X-Billed headers. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
One request returns PNG, JPEG, WebP, or PDF. The API supports full-page and CSS-selector captures, dark mode, device presets, custom viewports, retina scale, PDF settings, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Every feature is included on every plan. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. See the ScreenshotNeo API documentation for parameters and authentication.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Sign up for ScreenshotNeo to get 1,000 screenshots per month free with no card.
How to choose the right approach
| Requirement | Best fit | Reason |
|---|---|---|
| User selects a visible window or tab | Screen Capture API | The browser picker provides explicit consent and surface selection. |
| Capture a DOM element | Element or Region Capture | It can restrict or crop the stream, subject to support. |
| Capture a URL without a user present | ScreenshotNeo | One HTTP request handles rendering and image or PDF output. |
| Automate many URLs or use an AI agent | ScreenshotNeo | Bulk capture, asynchronous jobs, webhooks, and MCP tools are available. |
Further references
- MDN: MediaDevices.getDisplayMedia()
- MDN: Using the Screen Capture API
- MDN: Element Capture and Region Capture
- MDN: Screen Capture API overview
- W3C Screen Capture Editor’s Draft
Frequently Asked Questions
Can JavaScript capture a browser window without asking the user?
No. The Screen Capture API requires a browser picker and user approval for each request; a page cannot silently select an arbitrary window.
Does getDisplayMedia() return a PNG?
No. It returns a MediaStream. You must grab a frame, draw it to a canvas, and encode a Blob such as PNG, JPEG, or WebP.
Why should capture tracks be stopped?
Stopping every video track ends the active sharing session, releases resources, and prevents the browser from treating the page as still capturing.
Recommended Free Tools
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

