fix: guarantee loading indicator hides with 3-second timeout
TaxBaik CI/CD / build-and-deploy (push) Successful in 1m0s
TaxBaik CI/CD / build-and-deploy (push) Successful in 1m0s
**Issue**: Loading indicator remained visible, intercepting all user interactions (pointer-events: auto blocks clicks) **Root cause**: Multiple detection methods insufficient, race condition between JavaScript execution and Blazor initialization **Solution**: Add guaranteed 3-second timeout + multiple detection methods - Method 1: 3000ms timeout (guaranteed) - Method 2: Detect when 10+ MudBlazor components appear - Method 3: Hide when readystatechange to 'interactive' or 'complete' **Failsafe**: Even if Blazor never fires events, loading WILL hide after 3 seconds max **Result**: - Loading shows: immediate on page load - Loading hides: within 1-3 seconds (whichever is first) - User can interact: guaranteed by 3-second timeout at latest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -15,47 +15,37 @@ window.taxbaikAdminSession = {
|
|||||||
window.taxbaikAdminSession.syncRouteClass();
|
window.taxbaikAdminSession.syncRouteClass();
|
||||||
window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass);
|
window.addEventListener('popstate', window.taxbaikAdminSession.syncRouteClass);
|
||||||
|
|
||||||
// Show loading indicator on page load, hide when content renders
|
// Hide loading indicator after Blazor initializes
|
||||||
const loadingOverlay = document.getElementById('blazor-loading');
|
const loadingOverlay = document.getElementById('blazor-loading');
|
||||||
if (loadingOverlay) {
|
if (loadingOverlay) {
|
||||||
// Hide loading when page is fully interactive
|
|
||||||
// Watch for Blazor components to render
|
|
||||||
const hideLoading = () => {
|
const hideLoading = () => {
|
||||||
|
if (loadingOverlay.classList.contains('show')) {
|
||||||
loadingOverlay.classList.remove('show');
|
loadingOverlay.classList.remove('show');
|
||||||
document.removeEventListener('blazor:ready', hideLoading);
|
}
|
||||||
observer.disconnect();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide on Blazor ready event
|
// Method 1: Hide after 3 seconds (guaranteed timeout)
|
||||||
document.addEventListener('blazor:ready', hideLoading);
|
setTimeout(hideLoading, 3000);
|
||||||
|
|
||||||
// Also hide after DOM content loaded + small delay
|
// Method 2: Hide when Blazor components appear (faster if available)
|
||||||
if (document.readyState === 'loading') {
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (loadingOverlay.classList.contains('show')) {
|
|
||||||
hideLoading();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (loadingOverlay.classList.contains('show')) {
|
|
||||||
hideLoading();
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch for interactive elements to appear
|
|
||||||
const observer = new MutationObserver(() => {
|
const observer = new MutationObserver(() => {
|
||||||
const mudElements = document.querySelectorAll('[class*="mud-"]').length;
|
const mudElements = document.querySelectorAll('[class*="mud-"]').length;
|
||||||
if (mudElements > 20 && loadingOverlay.classList.contains('show')) {
|
if (mudElements > 10) {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
|
observer.disconnect();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
observer.observe(document.body, {
|
observer.observe(document.body, {
|
||||||
childList: true,
|
childList: true,
|
||||||
subtree: true
|
subtree: true,
|
||||||
|
attributes: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Method 3: Hide when page is interactive
|
||||||
|
document.addEventListener('readystatechange', () => {
|
||||||
|
if (document.readyState === 'interactive' || document.readyState === 'complete') {
|
||||||
|
setTimeout(hideLoading, 500);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user