/** * CDN资源加载检测和Fallback机制 * 自动检测CDN资源是否加载成功,失败时使用本地备份 * * 支持的资源: * - Bootstrap CSS * - Font Awesome * * 使用方法: * 在HTML的中引入此脚本: * */ (function() { 'use strict'; const CDNFallback = { /** * 检测Bootstrap CSS是否加载成功 */ checkBootstrapCSS: function() { const testEl = document.createElement('div'); testEl.className = 'container'; testEl.style.display = 'none'; document.body.appendChild(testEl); const hasBootstrap = window.getComputedStyle(testEl).maxWidth !== 'none'; document.body.removeChild(testEl); if (!hasBootstrap) { console.warn('⚠️ Bootstrap CSS加载失败,使用本地备份'); this.loadLocalCSS('/static/css/bootstrap.min.css'); return false; } else { console.log('✅ Bootstrap CSS加载成功'); return true; } }, /** * 检测Font Awesome是否加载成功 */ checkFontAwesome: function() { const testEl = document.createElement('i'); testEl.className = 'fas fa-check'; testEl.style.display = 'none'; document.body.appendChild(testEl); const computedStyle = window.getComputedStyle(testEl); const hasFontAwesome = computedStyle.fontFamily.includes('Font Awesome'); document.body.removeChild(testEl); if (!hasFontAwesome) { console.warn('⚠️ Font Awesome加载失败,使用本地备份'); this.loadLocalCSS('/static/css/font-awesome.min.css'); return false; } else { console.log('✅ Font Awesome加载成功'); return true; } }, /** * 检测Bootstrap JS是否加载成功 */ checkBootstrapJS: function() { if (typeof bootstrap === 'undefined') { console.warn('⚠️ Bootstrap JS加载失败,使用本地备份'); this.loadLocalJS('/static/js/bootstrap.bundle.min.js'); return false; } else { console.log('✅ Bootstrap JS加载成功'); return true; } }, /** * 检测Chart.js是否加载成功 */ checkChartJS: function() { if (typeof Chart === 'undefined') { console.warn('⚠️ Chart.js加载失败,使用本地备份'); this.loadLocalJS('/static/js/chart.min.js'); return false; } else { console.log('✅ Chart.js加载成功'); return true; } }, /** * 加载本地CSS文件 */ loadLocalCSS: function(url) { const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = url; link.onerror = function() { console.error('❌ 本地CSS备份也加载失败:', url); }; document.head.appendChild(link); }, /** * 加载本地JS文件 */ loadLocalJS: function(url) { const script = document.createElement('script'); script.src = url; script.onerror = function() { console.error('❌ 本地JS备份也加载失败:', url); }; document.head.appendChild(script); }, /** * 执行所有CSS检测 */ checkAllCSS: function() { this.checkBootstrapCSS(); this.checkFontAwesome(); }, /** * 执行所有JS检测 */ checkAllJS: function() { // Bootstrap JS需要在DOM加载完成后检测 if (document.querySelector('script[src*="bootstrap"]')) { this.checkBootstrapJS(); } // Chart.js需要在页面使用时才检测 if (document.querySelector('script[src*="chart"]')) { this.checkChartJS(); } }, /** * 初始化 - 自动检测所有资源 */ init: function() { const self = this; // CSS资源在DOM加载完成后立即检测 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { setTimeout(function() { self.checkAllCSS(); }, 100); }); } else { setTimeout(function() { self.checkAllCSS(); }, 100); } // JS资源在页面完全加载后检测 window.addEventListener('load', function() { setTimeout(function() { self.checkAllJS(); }, 200); }); } }; // 自动初始化 CDNFallback.init(); // 暴露到全局(可选,用于手动调用) window.CDNFallback = CDNFallback; })();