What Is the Selection API
The Selection API is a web standard that enables developers to programmatically access and manipulate the portion of a document that a user has selected. When users highlight text with their mouse or keyboard, the browser maintains an internal selection state. The Selection API provides a clean, JavaScript-based interface for reading this state and even modifying it directly from your code.
At its core, the Selection API consists of two main components: the Selection object retrieved through window.getSelection() or document.getSelection(), and the underlying Range objects that represent the actual selected content. The separation between the selection (the user's highlighted content) and ranges (the actual DOM representation) provides flexibility for complex scenarios like multi-range selections or selections that span multiple elements. MDN Web Docs
The API became widely available across browsers starting around 2015, making it a stable foundation for production applications. For developers building with Next.js and React, mastering these APIs opens possibilities for sophisticated text editing features without depending on heavy third-party libraries. Additionally, understanding how selections interact with SEO-friendly content structures ensures your interactive features don't compromise search visibility.
Core Concepts: Anchor, Focus, and Range
Understanding the Selection API requires grasping three foundational concepts that describe selection geometry. These concepts apply regardless of whether you're working with vanilla JavaScript or integrating selections into a React component lifecycle.
Anchor and Focus Points
Every selection has two endpoints that define its boundaries: the anchor and the focus. The anchor marks where the selection began, while the focus indicates where it ended. This distinction matters because users can select in either direction--they might drag left-to-right (anchor on the left, focus on the right) or right-to-left (anchor on the right, focus on the left). The anchorNode property returns the DOM Node where the selection begins, while focusNode returns the Node where it ended. MDN Web Docs
The anchorOffset and focusOffset properties provide precise positional information within those nodes--the number of characters from the start of the node to the respective endpoint. This granular access enables precise manipulation that respects the actual selection boundaries regardless of document structure.
Understanding the difference between anchor/focus and start/end is crucial for robust implementations. The isCollapsed property reveals whether the anchor and focus occupy the same position--a collapsed selection represents a caret position rather than a text selection.
Range Objects
Underlying every selection is one or more Range objects that represent the actual selected content in the DOM. A Range encompasses a contiguous portion of the document, including its start and end points. The Selection API provides methods like getRangeAt() to access these ranges and manipulate them directly. Ranges are powerful because they abstract away the complexity of DOM manipulation.
Selection Properties Reference
The Selection object exposes several read-only properties that describe the current selection in detail:
| Property | Description |
|---|---|
anchorNode | The DOM Node where the selection begins |
anchorOffset | Offset within the anchor node |
focusNode | The DOM Node where the selection ends |
focusOffset | Offset within the focus node |
isCollapsed | Whether anchor and focus are at the same position |
rangeCount | Number of ranges in the selection |
type | Describes the type of selection |
direction | Direction of the selection (forward/backward) |
The toString() method provides the plain text content of the selection, making it trivial to implement copy functionality. For implementations that need to preserve formatting, you'll work with the range's cloneContents() method or extract nodes from the range directly. When building AI-powered content tools, these selection properties help identify exact text regions for processing.
Key Methods for Modifying Selections
Beyond reading selections, the API provides methods for programmatically modifying the selection. These capabilities enable features like selecting all text, collapsing to endpoints, or programmatically extending selections based on application logic.
Collapsing and Extending
collapse(node, offset)- Move selection to a single pointcollapseToEnd()- Collapse to the end of current selectioncollapseToStart()- Collapse to the start of current selectionextend(node, offset)- Move the focus point while keeping anchor fixed
Range Management
addRange(range)- Add a range to the selectionremoveRange(range)- Remove a specific rangeremoveAllRanges()- Clear all selectionsgetRangeAt(index)- Get a specific range by index
Content Operations
toString()- Get plain text contentcontainsNode(node, partial)- Check if node is includeddeleteFromDocument()- Delete selected content from documentselectAllChildren(node)- Select all children of a node
The setBaseAndExtent() method offers a convenient way to set selection endpoints in a single call, specifying the anchor node, anchor offset, focus node, and focus offset together.
Code Examples
Retrieving the Selection
// Retrieve the current selection
const selection = window.getSelection();
// Check if there's an active selection
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
console.log('Selected text:', selection.toString());
}
Analyzing Selection Properties
function analyzeSelection(selection) {
if (selection.rangeCount === 0) {
return { hasSelection: false };
}
return {
hasSelection: true,
text: selection.toString(),
isCollapsed: selection.isCollapsed,
anchorNode: selection.anchorNode,
anchorOffset: selection.anchorOffset,
focusNode: selection.focusNode,
focusOffset: selection.focusOffset
};
}
Programmatic Selection
// Select an entire element
function selectElement(element) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
// Clear all selections
function clearSelection() {
const selection = window.getSelection();
selection.removeAllRanges();
}
Extracting Selected Content
// Extract selected content and insert elsewhere
function moveSelectionTo(targetContainer) {
const selection = window.getSelection();
if (selection.rangeCount === 0) return;
const range = selection.getRangeAt(0);
const content = range.extractContents();
targetContainer.appendChild(content);
selection.collapseToEnd();
}
Handling Selection Events
The Selection API includes events that fire when selections change, enabling reactive updates and synchronization with application state.
selectionchange Event
Fires on the Document whenever the current selection changes, whether through user interaction or programmatic modification:
document.addEventListener('selectionchange', () => {
const selection = window.getSelection();
updateSelectionUI(selection);
});
function updateSelectionUI(selection) {
const hasSelection = selection.toString().length > 0;
document.getElementById('copy-button').disabled = !hasSelection;
}
selectstart Event
Fires when a new selection begins, providing an opportunity to prevent selection in specific regions:
document.addEventListener('selectstart', (e) => {
// Prevent selection in certain areas
if (e.target.closest('.no-selection')) {
e.preventDefault();
}
});
The selectstart event is cancelable, allowing you to implement selection restrictions--for example, preventing selection in UI elements while allowing selection in content areas.
Performance Best Practices
While the Selection API is well-optimized in modern browsers, certain usage patterns can impact performance, especially in applications with complex DOMs or frequent selection updates.
Efficient Selection Operations
When working with selections in performance-critical code paths:
- Cache the Selection object when using it multiple times
- Batch operations together to avoid repeated range creation
- Use
toString()for text retrieval as it's highly optimized
Debounced Updates
For applications like text editors that process selections frequently, consider debouncing selection change handlers:
let updatePending = false;
document.addEventListener('selectionchange', () => {
if (updatePending) return;
updatePending = true;
requestAnimationFrame(() => {
const selection = window.getSelection();
processSelection(selection);
updatePending = false;
});
});
React Integration
For React applications, encapsulate selection logic in custom hooks:
function useSelection() {
const selectionRef = useRef(null);
const getSelection = useCallback(() => {
return window.getSelection();
}, []);
const clearSelection = useCallback(() => {
const selection = window.getSelection();
selection.removeAllRanges();
}, []);
return { getSelection, clearSelection };
}
When using selection functionality in Next.js applications, be aware that window and document are not available during server-side rendering. Guard selection operations behind typeof window !== 'undefined' checks, or use React's useEffect to ensure code only runs on the client. For AI automation workflows that process selected content, implement proper error handling for edge cases.
Common Use Cases
Custom Copy Functionality
Implementing a custom copy button requires retrieving the selected text and placing it on the clipboard. Modern applications can combine the Selection API with the Clipboard API:
async function copySelection() {
const selection = window.getSelection();
const text = selection.toString();
try {
await navigator.clipboard.writeText(text);
showCopySuccess();
} catch (err) {
fallbackCopy(text);
}
}
Rich Text Editor Integration
Rich text editors use the Selection API to maintain cursor position and selection state across operations. By tracking selection endpoints as Range objects, editors can restore focus after applying formatting or inserting content. The ability to programmatically select content enables features like selecting all, find-and-replace results, and syntax highlighting that responds to cursor position.
Annotation Systems
Modern documentation tools anchor annotations to specific text passages. Save selection snapshots using Range objects to restore selections later, enabling threaded comments on selected text. This is essential for building collaborative features that require precise text anchoring. When implementing these features for enterprise web applications, consider performance implications for large documents with frequent selection operations.
Best Practices Summary
Cross-Browser Compatibility
The Selection API is well-supported across modern browsers, but subtle differences exist in how selections interact with form elements, editable content, and specific HTML elements. Test selection behavior across target browsers, particularly for edge cases like selecting in input fields versus regular content areas.
Accessibility
When implementing custom selection features, ensure keyboard accessibility matches mouse interactions. Many users navigate and select text using keyboard shortcuts like Shift+Arrow. Additionally, communicate selection state visually for users who may not perceive native selection highlighting.
User Experience
- Respect user intent when implementing selection manipulation
- Avoid clearing selections without user action
- Provide multiple ways to select content for different preferences
- Provide clear visual feedback about what is selected
Next.js Considerations
- Guard selection operations behind
typeof window !== 'undefined'checks - Use React's
useEffectfor client-only selection logic - Handle hydration properly to avoid SSR mismatches
- Consider using refs instead of state for selection objects to prevent unnecessary re-renders
By following these practices, you can build robust selection-aware features that enhance user experience across your web applications. For teams looking to implement advanced selection features at scale, consider partnering with specialized web development services that have deep expertise in modern JavaScript APIs.
Frequently Asked Questions
Sources
- MDN Web Docs: Selection API - Primary API documentation with interfaces and methods
- MDN Web Docs: Selection Interface - Selection object reference with anchor/focus concepts, properties, and methods
- W3C Selection API Specification - Official specification defining the standard