// 错误处理和兼容性脚本 (function() { 'use strict'; // 全局错误处理 window.addEventListener('error', function(event) { console.error('Global error:', { message: event.message, filename: event.filename, lineno: event.lineno, colno: event.colno, error: event.error }); // 发送错误到控制台(便于调试) if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { console.group('Error Details:'); console.log('Message:', event.message); console.log('File:', event.filename); console.log('Line:', event.lineno + ':' + event.colno); if (event.error && event.error.stack) { console.log('Stack:', event.error.stack); } console.groupEnd(); } return true; // 阻止默认错误处理 }); // Promise 错误处理 window.addEventListener('unhandledrejection', function(event) { console.error('Unhandled promise rejection:', event.reason); if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { console.group('Promise Rejection:'); console.log('Reason:', event.reason); if (event.reason && event.reason.stack) { console.log('Stack:', event.reason.stack); } console.groupEnd(); } event.preventDefault(); // 阻止默认处理 }); // DOM 查询安全包装 function safeQuerySelector(selector) { try { return document.querySelector(selector); } catch (e) { console.warn('Invalid selector:', selector, e); return null; } } function safeQuerySelectorAll(selector) { try { return document.querySelectorAll(selector); } catch (e) { console.warn('Invalid selector:', selector, e); return []; } } // 安全的getElementById function safeGetElementById(id) { try { return document.getElementById(id); } catch (e) { console.warn('Invalid element ID:', id, e); return null; } } // 修复常见的兼容性问题 function fixCompatibilityIssues() { // 修复classList不支持的情况(简化版本以避免Illegal invocation) try { // 安全检测classList支持 var testElement = document.createElement('div'); if (!testElement.classList) { // 简单的classList polyfill window.ClassListPolyfill = { addClass: function(element, className) { if (element && className) { var classes = element.className ? element.className.split(' ') : []; if (classes.indexOf(className) === -1) { classes.push(className); element.className = classes.join(' ').trim(); } } }, removeClass: function(element, className) { if (element && className) { var classes = element.className ? element.className.split(' ') : []; var index = classes.indexOf(className); if (index !== -1) { classes.splice(index, 1); element.className = classes.join(' ').trim(); } } }, hasClass: function(element, className) { if (!element || !className) return false; var classes = element.className ? element.className.split(' ') : []; return classes.indexOf(className) !== -1; } }; } } catch (e) { // 如果检测失败,忽略错误 console.warn('classList detection failed:', e); } // 修复addEventListener不支持的情况 if (!Element.prototype.addEventListener && Element.prototype.attachEvent) { Element.prototype.addEventListener = function(event, listener) { this.attachEvent('on' + event, listener); }; Element.prototype.removeEventListener = function(event, listener) { this.detachEvent('on' + event, listener); }; } // 修复Array.from不支持的情况 if (!Array.from) { Array.from = function(arrayLike) { var result = []; for (var i = 0; i < arrayLike.length; i++) { result.push(arrayLike[i]); } return result; }; } // 修复forEach不支持的情况 if (!NodeList.prototype.forEach) { NodeList.prototype.forEach = function(callback, thisArg) { for (var i = 0; i < this.length; i++) { callback.call(thisArg, this[i], i, this); } }; } } // 检测浏览器支持情况 function detectBrowserSupport() { const features = { es6: { arrow: false, const: false, let: false, template: false, destructuring: false }, dom: { classList: (function() { try { var testElement = document.createElement('div'); return !!testElement.classList; } catch (e) { return false; } })(), querySelector: !!document.querySelector, addEventListener: !!window.addEventListener }, css: { grid: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('display', 'grid'), flexbox: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('display', 'flex'), transform: typeof CSS !== 'undefined' && CSS.supports && CSS.supports('transform', 'translateX(0)') } }; // 测试ES6功能 try { eval('const x = 1'); features.es6.const = true; } catch (e) {} try { eval('let x = 1'); features.es6.let = true; } catch (e) {} try { eval('`template`'); features.es6.template = true; } catch (e) {} try { eval('() => {}'); features.es6.arrow = true; } catch (e) {} if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { console.group('Browser Support:'); console.table(features); console.groupEnd(); } return features; } // 修复具体的错误 function fixSpecificErrors() { // 确保所有必要的元素存在 const requiredElements = [ 'navbar', 'mobile-menu-button', 'mobile-menu', 'mobile-menu-overlay', 'close-menu' ]; setTimeout(function() { requiredElements.forEach(function(id) { const element = document.getElementById(id); if (!element) { console.warn('Missing required element:', id); // 尝试创建缺失的元素(某些情况下) if (id === 'mobile-menu-overlay' && !document.getElementById(id)) { const overlay = document.createElement('div'); overlay.id = id; overlay.className = 'mobile-menu-overlay hidden'; document.body.appendChild(overlay); console.log('Created missing overlay element'); } } }); }, 1000); } // 安全的脚本加载 function safeLoadScript(src, callback) { const script = document.createElement('script'); script.src = src; script.onload = function() { if (callback) callback(); }; script.onerror = function() { console.error('Failed to load script:', src); }; document.head.appendChild(script); } // 初始化错误处理 function init() { // 修复兼容性问题 fixCompatibilityIssues(); // 检测浏览器支持 detectBrowserSupport(); // 修复具体错误 fixSpecificErrors(); // 为调试添加全局工具 if (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1') { window.debugTools = { safeQuerySelector: safeQuerySelector, safeQuerySelectorAll: safeQuerySelectorAll, safeGetElementById: safeGetElementById, fixCompatibilityIssues: fixCompatibilityIssues, detectBrowserSupport: detectBrowserSupport }; } console.log('Error handler initialized'); } // 在DOM加载后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();