fix: guarantee loading indicator hides with 3-second timeout
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:
2026-06-28 15:04:39 +09:00
parent 79d99cfd7a
commit 27f57ff925
+18 -28
View File
@@ -15,47 +15,37 @@ window.taxbaikAdminSession = {
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');
if (loadingOverlay) {
// Hide loading when page is fully interactive
// Watch for Blazor components to render
const hideLoading = () => {
loadingOverlay.classList.remove('show');
document.removeEventListener('blazor:ready', hideLoading);
observer.disconnect();
if (loadingOverlay.classList.contains('show')) {
loadingOverlay.classList.remove('show');
}
};
// Hide on Blazor ready event
document.addEventListener('blazor:ready', hideLoading);
// Method 1: Hide after 3 seconds (guaranteed timeout)
setTimeout(hideLoading, 3000);
// Also hide after DOM content loaded + small delay
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
// Method 2: Hide when Blazor components appear (faster if available)
const observer = new MutationObserver(() => {
const mudElements = document.querySelectorAll('[class*="mud-"]').length;
if (mudElements > 20 && loadingOverlay.classList.contains('show')) {
if (mudElements > 10) {
hideLoading();
observer.disconnect();
}
});
observer.observe(document.body, {
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);
}
});
}