The Modern Approach — Vanilla JavaScript + fetch()
In 2026 there is no need for a jQuery dependency to implement a loading overlay. The native Fetch API combined with a simple CSS overlay handles this pattern cleanly in every modern browser.
HTML
<!-- Loading overlay -->
<div id="loading-overlay" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.4); z-index:9999; align-items:center; justify-content:center;">
<div style="color:#fff; font-size:1.5rem;">Loading…</div>
</div>
<button id="load-btn">Load Data</button>
<div id="result"></div>
JavaScript
const overlay = document.getElementById('loading-overlay');
const resultDiv = document.getElementById('result');
document.getElementById('load-btn').addEventListener('click', async () => {
// Show overlay
overlay.style.display = 'flex';
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const data = await response.json();
resultDiv.textContent = data.title;
} catch (err) {
resultDiv.textContent = 'Error loading data.';
} finally {
// Always hide overlay, even on error
overlay.style.display = 'none';
}
});
When the button is clicked, the overlay is set to display:flex (so the inner text centres correctly). The fetch() call runs inside a try/catch block so errors are handled gracefully. The finally block runs regardless of success or failure, which guarantees the overlay is always hidden when the request completes.
Legacy Approach — jQuery (for existing jQuery projects)
If your project already includes jQuery, the $.ajax() approach still works perfectly well — there is no need to refactor existing code. Use beforeSend to show the overlay and complete to hide it (the complete callback fires after both success and error, making it the reliable equivalent of finally).
$('#load-btn').on('click', function () {
$.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1',
beforeSend: function () {
$('#loading-overlay').show();
},
success: function (data) {
$('#result').text(data.title);
},
error: function () {
$('#result').text('Error loading data.');
},
complete: function () {
$('#loading-overlay').hide();
}
});
});
fetch() vs jQuery.ajax() — Quick Comparison
| fetch() | jQuery.ajax() | |
|---|---|---|
| Library required | None (native) | jQuery |
| Returns | Promise | jqXHR |
| Error handling | try/catch | error callback |
| Browser support | All modern browsers | All (with jQuery) |
| Recommended for new projects | Yes | No (unless jQuery already in use) |
Frequently Asked Questions
Do I still need jQuery for AJAX loading in 2026?
No. The Fetch API is natively supported in all modern browsers. jQuery’s .ajax() is still a valid option if you’re already using jQuery, but there is no reason to add jQuery just for AJAX requests.
How do I prevent the overlay from blocking user interactions beneath it?
If you want users to be able to cancel or still scroll the page while loading, add pointer-events: none to the overlay CSS. Otherwise, the full-cover overlay with no pointer-events change will block all clicks, which is usually intentional (prevents double-submit).
Does this work with React, Vue, or Angular?
The same concept applies. In React, use a useState boolean (isLoading) to conditionally render the overlay. In Vue, bind v-if="isLoading". In Angular, use an *ngIf directive. The overlay pattern is framework-agnostic.
For new projects in 2026, fetch() paired with a CSS overlay is the recommended approach — no extra dependencies, clean async/await syntax, and reliable error handling via finally. If jQuery is already in your stack, the $.ajax() pattern remains a perfectly valid alternative.