What is TextTrackList?
TextTrackList is a JavaScript interface that represents an ordered collection of text tracks associated with a media element. Each text track in the list contains timed text content such as subtitles, captions, chapters, or metadata that can be displayed or processed alongside video or audio playback. The interface inherits from EventTarget, which means it can emit and respond to events when tracks are added, removed, or changed.
The TextTrackList for a given media element is accessed through the textTracks property of the HTMLMediaElement interface, which includes both HTMLVideoElement and HTMLAudioElement. This means any <video> or <audio> element in your HTML provides access to its associated TextTrackList through JavaScript. Our web development services team regularly implements these interfaces for media-rich applications.
Each individual track within the TextTrackList is represented by a TextTrack object, which contains the actual cue data and metadata for that track. The TextTrackList itself provides methods for querying and manipulating the collection of tracks, while individual TextTrack objects handle the specific content and behavior of each track.
Understanding this hierarchy is essential for effective media accessibility implementation. You work with the TextTrackList to manage the collection of tracks, and you work with individual TextTrack objects to work with the actual subtitle or caption content within each track.
Accessing TextTrackList
Accessing the TextTrackList for any media element is straightforward using the textTracks property. This property is available on all HTMLMediaElement instances, including video and audio elements. The property returns a live TextTrackList object that reflects the current state of text tracks associated with the element.
Code Example: Basic Access
// Get the textTracks collection from a video element
const videoElement = document.querySelector('video');
const textTrackList = videoElement.textTracks;
// Access the length property to see how many tracks exist
console.log(`Number of text tracks: ${textTrackList.length}`);
The TextTrackList behaves like a standard array-like object, allowing you to access individual tracks by index. However, it also provides specialized methods for more complex operations such as finding tracks by their ID.
// Access individual tracks by index
for (let i = 0; i < textTrackList.length; i++) {
const track = textTrackList[i];
console.log(`Track ${i}: ${track.label} (${track.kind})`);
}
// Use array-like iteration (note: not a true Array)
Array.from(textTrackList).forEach(track => {
console.log(track.language);
});
It is important to note that the TextTrackList is live, meaning it automatically updates when tracks are added or removed from the associated media element. This live behavior has performance implications that developers should understand when iterating over the collection or performing multiple operations.
Properties of TextTrackList
The TextTrackList interface provides a minimal but essential set of properties that enable developers to inspect and work with the collection of text tracks. Understanding these properties is fundamental to building robust media accessibility features.
Length Property
The length property returns the number of text tracks in the TextTrackList. This read-only property is the primary way to determine how many tracks are associated with a media element. The length value updates automatically as tracks are added or removed, reflecting the current state of the collection.
const videoElement = document.querySelector('video');
const trackCount = videoElement.textTracks.length;
if (trackCount === 0) {
console.log('No text tracks available');
} else if (trackCount === 1) {
console.log('One text track available');
} else {
console.log(`${trackCount} text tracks available`);
}
The length property is essential for iteration and validation. Before accessing tracks by index or performing operations that expect tracks to exist, you should always check the length to avoid errors. This property is particularly useful when building UI components that need to display information about available tracks or when implementing features that depend on the presence of specific track types.
EventTarget Inheritance
Since TextTrackList inherits from EventTarget, it supports the standard event model used throughout the DOM. This inheritance provides the foundation for handling track-related events, though specific event handling is typically done at the TextTrack level rather than the list level.
Methods of TextTrackList
The TextTrackList interface provides one primary method for querying tracks within the collection. While the collection supports array-like access by index, the dedicated method provides more flexible lookup capabilities.
getTrackById()
The getTrackById() method searches the TextTrackList for a track with a matching ID and returns the first matching TextTrack object. If no matching track is found, the method returns null. This method enables efficient lookup of specific tracks when you know their identifier, which is particularly useful when working with dynamically created tracks or when tracks have been assigned meaningful IDs.
const videoElement = document.querySelector('video');
const textTrackList = videoElement.textTracks;
// Find a track by its ID
const englishCaptions = textTrackList.getTrackById('en-captions');
if (englishCaptions) {
console.log('Found English captions track');
englishCaptions.mode = 'showing';
} else {
console.log('English captions track not found');
}
The ID used with getTrackById() corresponds to the id property of the TextTrack object. When tracks are created declaratively using the <track> element, the track's ID matches the element's ID attribute. When tracks are created programmatically using addTextTrack(), the ID can be specified as a parameter or left empty for automatic assignment.
// Creating a track with a specific ID
const video = document.querySelector('video');
const track = video.addTextTrack('captions', 'English Captions', 'en');
track.id = 'primary-captions';
// Later, retrieve it by ID
const retrievedTrack = video.textTracks.getTrackById('primary-captions');
It is worth noting that the getTrackById() method differs from index-based access in that it searches by identifier rather than position. This makes it more robust when the order of tracks might change or when you need to identify a specific track regardless of its position in the list.
Events and Event Handling
The TextTrackList interface supports several events that allow developers to respond to changes in the collection of text tracks. These events are essential for building dynamic media interfaces that adapt to changing track availability or user preferences.
Addtrack Event
The addtrack event fires whenever a new text track is added to the TextTrackList. This can occur through declarative HTML markup when the page loads, or programmatically when tracks are added using JavaScript. The event provides an opportunity to update UI elements, initialize track-specific features, or log analytics about track availability.
const videoElement = document.querySelector('video');
const textTrackList = videoElement.textTracks;
// Using event listener
textTrackList.addEventListener('addtrack', event => {
const newTrack = event.track;
console.log(`New track added: ${newTrack.label} (${newTrack.kind})`);
updateTrackSelectorUI();
});
The event object for addtrack includes a track property that references the newly added TextTrack object.
Removetrack Event
The removetrack event fires when a text track is removed from the TextTrackList. While less common than track addition, this event is important for applications that dynamically manage tracks or work with streaming content where tracks may come and go.
textTrackList.addEventListener('removetrack', event => {
const removedTrack = event.track;
console.log(`Track removed: ${removedTrack.label}`);
updateTrackSelectorUI();
});
Change Event
The change event fires when a track's mode changes or when the active state of tracks in the list changes. This event is useful for monitoring user interactions with track selection or responding to changes in which tracks are currently visible or active.
textTrackList.addEventListener('change', event => {
console.log('Track list has changed');
// Check which tracks are now showing
for (let i = 0; i < textTrackList.length; i++) {
const track = textTrackList[i];
if (track.mode === 'showing') {
console.log(`Active track: ${track.label}`);
}
}
});
Integration with HTML Media Elements
TextTrackList is intrinsically linked to HTML media elements, and understanding how tracks are associated with these elements is fundamental to effective implementation. There are two primary methods for associating text tracks with media content: declarative HTML markup and programmatic JavaScript addition.
Declarative Track Addition with the Track Element
The <track> element allows you to specify text tracks directly in HTML markup. When the browser processes a media element containing <track> children, it automatically creates the corresponding TextTrack objects and adds them to the media element's TextTrackList.
<video controls width="640" height="360">
<source src="video.mp4" type="video/mp4">
<source src="video.webm" type="video/webm">
<track label="English" kind="captions" srclang="en" src="captions-en.vtt" default>
<track label="Spanish" kind="captions" srclang="es" src="captions-es.vtt">
</video>
Each <track> element creates a TextTrack with properties derived from its attributes:
- The
kindattribute determines the track type (captions, subtitles, chapters, metadata, descriptions) - The
labelattribute provides a human-readable name for the track - The
srclangattribute specifies the language code (BCP 47 format) - The
srcattribute points to the WebVTT file containing the cue data - The
defaultattribute marks the track as initially enabled
Programmatic Track Addition with addTextTrack()
The addTextTrack() method on HTMLMediaElement allows you to create and add text tracks dynamically using JavaScript. This method is useful when you need to generate tracks on the fly, work with data from APIs, or create tracks for which you have the cue data available programmatically. When building modern web applications, programmatic track creation enables dynamic caption generation from various data sources.
const videoElement = document.querySelector('video');
// Add a new captions track
const captionsTrack = videoElement.addTextTrack(
'captions', // kind
'English Captions', // label
'en' // language
);
// Show the track
captionsTrack.mode = 'showing';
Understanding Track Modes
Each TextTrack has a mode property that controls its visibility and behavior:
disabled: The track is parsed but not displayedhidden: The track is parsed and cues are processed, but not displayedshowing: The track is displayed to the user
Best Practices for TextTrackList Management
Effective management of TextTrackList requires attention to performance, accessibility, and user experience. The following best practices will help you build robust media accessibility features for your web projects.
Performance Optimization
TextTrackList operations are generally efficient, but there are considerations for maintaining performance in applications with complex media requirements. The live nature of the TextTrackList means that modifications to the collection trigger updates throughout the system.
When iterating over a TextTrackList, be aware that the collection is live. If you add or remove tracks during iteration, the length changes dynamically, which can lead to unexpected behavior. It is often safer to create a snapshot of the tracks you want to work with.
const videoElement = document.querySelector('video');
const textTrackList = videoElement.textTracks;
// Create a snapshot to avoid live collection issues during iteration
const tracksSnapshot = Array.from(textTrackList);
tracksSnapshot.forEach(track => {
// Process each track safely
console.log(track.label);
});
Accessibility Considerations
TextTrackList management is fundamentally about accessibility, and there are several practices that ensure your implementation serves all users effectively.
Always provide meaningful labels for tracks. The label property is what users see when selecting tracks through your player interface or the browser's native controls. Tracks without labels may be confusing or inaccessible to users.
Consider providing multiple track options for different languages or purposes. Users should be able to select their preferred language or disable captions entirely.
Error Handling
Track loading can fail due to invalid WebVTT files, network errors, or CORS issues. Your implementation should handle these errors gracefully.
const videoElement = document.querySelector('video');
const textTrackList = videoElement.textTracks;
textTrackList.addEventListener('addtrack', event => {
const track = event.track;
track.oncueerror = event => {
console.error(`Error loading cues for track: ${track.label}`);
// Provide fallback or notify user
};
});
Cross-Browser Compatibility
While TextTrackList is well-supported across modern browsers, the interface has been part of the HTML specification since 2015 and is considered baseline widely available across all modern browsers.
Related Interfaces and APIs
TextTrackList does not exist in isolation--it is part of a broader ecosystem of interfaces that together enable comprehensive text track management. Understanding these related interfaces will help you implement more sophisticated text track features for your web development projects.
TextTrack represents an individual track within the TextTrackList. While TextTrackList manages the collection, TextTrack provides access to the actual cue data and track-specific properties. Each TextTrack has properties like kind, label, language, and mode that describe the track's purpose and current state.
VTTCue (Video Text Tracks Cue) represents a single cue within a text track. Cues are the individual pieces of timed text that appear during playback. The VTTCue interface provides properties for controlling cue timing, text content, positioning, and styling.
TextTrackCueList represents a collection of cues within a track. Similar to how TextTrackList manages TextTrack objects, TextTrackCueList manages VTTCue objects. This interface provides methods for accessing and querying cues by time range.
WebVTT encompasses all these interfaces and provides the foundation for working with timed text in web media. WebVTT files use a specific format for defining cues, and the browser's WebVTT parser handles converting this format into the JavaScript objects described above.
Essential features for managing text tracks in modern web applications
Track Collection Management
Access and manipulate collections of text tracks associated with video and audio elements through a unified interface.
Event-Driven Updates
Respond to track changes in real-time using addtrack, removetrack, and change events.
ID-Based Lookup
Efficiently find specific tracks using the getTrackById() method for targeted operations.
Cross-Browser Support
Built on web standards with broad support across all modern browsers since 2015.