The Document Object Model (DOM) is just one of many Web APIs available in the browser. Web APIs extend JavaScript's capabilities, allowing you to access powerful features built into the user's browser, such as their location, the ability to manipulate files, and control the browser's navigation history.
1. The Geolocation API (User Location)
The Geolocation API allows a web application to access the user's location (with their permission). The core object is accessed via navigator.geolocation. This is an asynchronous operation.
Retrieving Current Position
JavaScript
function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition, handleError);
    } else {
        console.error("Geolocation is not supported by this browser.");
    }
}
function showPosition(position) {
    const lat = position.coords.latitude;
    const lon = position.coords.longitude;
    console.log(`Latitude: ${lat}, Longitude: ${lon}`);
    // You would typically display this on a map
}
function handleError(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED:
            console.error("User denied the request for Geolocation.");
            break;
        case error.POSITION_UNAVAILABLE:
            console.error("Location information is unavailable.");
            break;
        case error.TIMEOUT:
            console.error("The request to get user location timed out.");
            break;
    }
}
getLocation();
2. The Drag and Drop API
The HTML Drag and Drop API enables applications to support dragging elements from one location to another. You need to handle three key event groups: dragstart, dragover, and drop.
Making an Element Draggable (Source)
Set the draggable="true" attribute on the element and listen for dragstart to store the data being dragged.
JavaScript
const draggableItem = document.getElementById('item');
draggableItem.addEventListener('dragstart', (e) => {
    // Store data (e.g., the element's ID)
    e.dataTransfer.setData('text/plain', e.target.id);
    e.dataTransfer.effectAllowed = 'move';
});
Defining a Drop Target
Listen for dragover and drop on the target element. Crucially, you must call e.preventDefault() in the dragover handler to make the element a valid drop zone.
JavaScript
const dropZone = document.getElementById('dropzone');
dropZone.addEventListener('dragover', (e) => {
    e.preventDefault(); // Essential: allows the element to be dropped
});
dropZone.addEventListener('drop', (e) => {
    e.preventDefault();
    const data = e.dataTransfer.getData('text/plain');
    const draggedElement = document.getElementById(data);
    
    // Move the element into the drop zone
    dropZone.appendChild(draggedElement);
    console.log(`Dropped item: ${data}`);
});
3. The History API
The History API allows you to manipulate the browser's session history programmatically, crucial for building Single Page Applications (SPAs) that change the view without a full page reload.
history.pushState(state, title, url): Pushes a new entry onto the browser history stack. It changes the URL in the address bar without reloading the page.
history.replaceState(state, title, url): Replaces the current entry in the browser history stack.
window.onpopstate: An event fired when the user clicks the browser's back or forward buttons.
JavaScript
// Function to simulate changing a page/view in an SPA
function changePage(pageName, data) {
    // 1. Update the content on the page (DOM manipulation)
    document.getElementById('content').textContent = `Now viewing: ${pageName}`;
    // 2. Change the URL without a full reload
    history.pushState({ view: pageName, ...data }, pageName, `/${pageName.toLowerCase()}`);
}
// Handle the user clicking back/forward
window.onpopstate = (e) => {
    if (e.state && e.state.view) {
        // Use the state object to restore the correct view
        console.log(`Navigating back to: ${e.state.view}`);
        document.getElementById('content').textContent = `Now viewing: ${e.state.view} (Restored)`;
    }
};
// Example usage:
// changePage('About', { version: 1.2 });
// The URL will change to /about, but the page stays loaded.