/** * GSAP与Elementor兼容性管理器 * GSAP and Elementor Compatibility Manager * * 此文件确保GSAP动画与Elementor内置动画系统的兼容性 * This file ensures compatibility between GSAP animations and Elementor's built-in animation system * * @package Nenghui Energy Theme * @since 1.0.0 */ (function() { 'use strict'; // GSAP与Elementor兼容性管理器 const GSAPElementorCompatibility = { initialized: false, elementorAnimations: new Set(), gsapAnimations: new Set(), // 初始化 init: function() { if (this.initialized) return; // 添加页面就绪状态标记 document.body.classList.add('gsap-ready'); // 设置GSAP默认值 this.setupGSAPDefaults(); // 设置Elementor钩子 this.setupElementorHooks(); // 设置备用兼容性检查 this.setupFallbackCompatibility(); this.initialized = true; // 触发初始化完成事件 const event = new CustomEvent('gsapCompatibilityReady'); document.dispatchEvent(event); }, // 等待依赖加载 waitForDependencies: function(callback) { let attempts = 0; const maxAttempts = 100; // 增加等待时间到10秒 const checkDependencies = () => { attempts++; const gsapReady = window.gsap && window.ScrollTrigger; const elementorReady = window.elementorFrontend && window.elementorFrontend.hooks; if (gsapReady) { // GSAP准备好了,检查Elementor状态 if (elementorReady || attempts > 30) { // Elementor也准备好了,或者已经等待足够长时间 callback(); } else { // 继续等待Elementor setTimeout(checkDependencies, 100); } } else if (attempts < maxAttempts) { // 继续等待GSAP setTimeout(checkDependencies, 100); } else { // 超时,但仍然尝试继续 callback(); } }; checkDependencies(); }, // 设置兼容性 setupCompatibility: function() { // 设置GSAP默认值和基础配置 this.setupGSAPDefaults(); // 检查Elementor是否可用且hooks已准备好 if (window.elementorFrontend && window.elementorFrontend.hooks && typeof window.elementorFrontend.hooks.addAction === 'function') { this.setupElementorHooks(); } else { // 延迟再次检查Elementor setTimeout(() => { if (window.elementorFrontend && window.elementorFrontend.hooks) { this.setupElementorHooks(); } }, 1000); } this.setupScrollTriggerCompatibility(); this.setupAnimationConflictResolution(); this.setupGlobalAnimationManager(); }, // 设置Elementor兼容性钩子 - 改进版本 setupElementorHooks: function() { // 检查Elementor是否可用 if (typeof elementorFrontend !== 'undefined' && elementorFrontend.hooks) { this.initElementorHooks(); } else { // 监听Elementor前端加载事件 document.addEventListener('DOMContentLoaded', () => { // 使用更长的延迟确保Elementor完全加载 setTimeout(() => { if (typeof elementorFrontend !== 'undefined' && elementorFrontend.hooks) { this.initElementorHooks(); } else { this.setupFallbackCompatibility(); } }, 2000); // 增加延迟到2秒 }); } }, // 初始化Elementor钩子 initElementorHooks: function() { try { // 检查elementorFrontend和hooks是否存在 if (!elementorFrontend || !elementorFrontend.hooks || typeof elementorFrontend.hooks.addAction !== 'function') { return; } // 监听Elementor元素准备就绪事件 elementorFrontend.hooks.addAction('frontend/element_ready/global', (scope) => { this.handleElementorElementReady(scope); }); // 监听Elementor动画开始事件 elementorFrontend.hooks.addAction('frontend/element_ready/widget', (scope) => { this.handleElementorWidgetReady(scope); }); // 监听页面加载完成 if (elementorFrontend.hooks && typeof elementorFrontend.hooks.addAction === 'function') { elementorFrontend.hooks.addAction('frontend/init', () => { this.onElementorFrontendInit(); }); } } catch (error) { this.setupFallbackCompatibility(); } }, // 备用兼容性方案 setupFallbackCompatibility: function() { // 使用MutationObserver监听DOM变化 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { // 验证节点是否为有效的DOM元素 if (node && node.nodeType === Node.ELEMENT_NODE) { // 检查是否是Elementor元素 if (node.classList && ( node.classList.contains('elementor-element') || node.classList.contains('elementor-widget') || node.querySelector('.elementor-element') )) { // 添加延迟以确保元素完全加载 setTimeout(() => { this.handleElementorElement(node); }, 100); } } }); } }); }); observer.observe(document.body, { childList: true, subtree: true }); // 处理已存在的Elementor元素 setTimeout(() => { const existingElements = document.querySelectorAll('.elementor-element, .elementor-widget'); existingElements.forEach(element => { // 验证元素有效性 if (element && element.nodeType === Node.ELEMENT_NODE) { this.handleElementorElement(element); } }); }, 1000); }, // 处理Elementor元素 handleElementorElement: function(element) { // 延迟处理,确保Elementor动画已初始化 setTimeout(() => { // 检查元素是否有动画设置 const hasAnimation = element.classList.contains('elementor-invisible') || element.hasAttribute('data-settings') || element.querySelector('[data-settings*="animation"]'); if (hasAnimation) { // 暂停该元素的GSAP动画 this.pauseGSAPForElement(element); // 监听Elementor动画完成 this.waitForElementorAnimation(element, () => { this.enableGSAPForElement(element); }); } else { // 没有Elementor动画,可以安全使用GSAP this.enableGSAPForElement(element); } }, 500); }, // 暂停元素的GSAP动画 pauseGSAPForElement: function(element) { if (window.gsap) { gsap.killTweensOf(element); gsap.killTweensOf(element.querySelectorAll('*')); element.setAttribute('data-gsap-paused', 'true'); } }, // 启用元素的GSAP动画 enableGSAPForElement: function(element) { element.removeAttribute('data-gsap-paused'); element.setAttribute('data-gsap-ready', 'true'); // 触发自定义事件,通知GSAP动画可以开始 const event = new CustomEvent('gsapElementReady', { detail: { element: element } }); element.dispatchEvent(event); }, // 等待Elementor动画完成 waitForElementorAnimation: function(element, callback) { let attempts = 0; const maxAttempts = 50; // 5秒超时 const checkAnimation = () => { // 检查元素是否还有elementor-invisible类 if (!element.classList.contains('elementor-invisible')) { callback(); return; } attempts++; if (attempts < maxAttempts) { setTimeout(checkAnimation, 100); } else { callback(); // 超时也执行回调 } }; checkAnimation(); }, // 处理Elementor元素 handleElementorElement: function(scope) { // 验证scope参数 if (!scope) { return; } // 确保scope是DOM元素或jQuery对象 let element; if (scope.jquery) { // 如果是jQuery对象,获取第一个DOM元素 element = scope[0]; } else if (scope.nodeType === Node.ELEMENT_NODE) { // 如果是DOM元素 element = scope; } else { return; } // 验证最终的DOM元素 if (!element || !element.nodeType || element.nodeType !== Node.ELEMENT_NODE) { return; } const $scope = jQuery(element); // 检查是否有Elementor动画 const hasElementorAnimation = $scope.find('[data-settings*="animation"]').length > 0 || $scope.hasClass('elementor-invisible') || $scope.find('.elementor-invisible').length > 0; if (hasElementorAnimation) { this.elementorAnimations.add(element); // 为有Elementor动画的元素添加标记 $scope.attr('data-has-elementor-animation', 'true'); // 延迟初始化GSAP动画,避免冲突 setTimeout(() => { this.initGSAPForElement(element); }, 300); } else { // 没有Elementor动画的元素可以立即初始化GSAP this.initGSAPForElement(element); } }, // 为元素初始化GSAP动画 initGSAPForElement: function(element) { // 验证元素是否存在且为有效的DOM元素 if (!element || !element.nodeType || element.nodeType !== Node.ELEMENT_NODE) { return; } // 检查元素是否已经有GSAP动画 if (element.hasAttribute('data-gsap-initialized')) return; // 标记为已初始化 element.setAttribute('data-gsap-initialized', 'true'); // 这里可以添加特定的GSAP动画逻辑 // 例如:hover效果、滚动触发动画等 }, // 暂停冲突的GSAP动画 pauseConflictingGSAPAnimations: function(scope) { const gsapElements = scope.querySelectorAll('[data-gsap-initialized]'); gsapElements.forEach(element => { // 暂停该元素上的所有GSAP动画 gsap.killTweensOf(element); }); }, // 设置GSAP默认值 setupGSAPDefaults: function() { if (!window.gsap) { return; } // 设置GSAP默认缓动函数,与Elementor保持一致 gsap.defaults({ ease: "power2.out", duration: 0.6, overwrite: "auto" // 自动覆盖冲突的动画 }); // 设置ScrollTrigger默认值 if (window.ScrollTrigger) { ScrollTrigger.defaults({ toggleActions: "play none none reverse", markers: false, scroller: window, // 确保使用正确的滚动容器 refreshPriority: 1 // 提高刷新优先级 }); // 注册ScrollTrigger插件 gsap.registerPlugin(ScrollTrigger); } // 禁用GSAP的自动CSS前缀,避免与Elementor冲突 gsap.config({ autoSleep: 60, force3D: false, // 避免强制3D变换 nullTargetWarn: false // 减少警告信息 }); }, // 设置ScrollTrigger兼容性 setupScrollTriggerCompatibility: function() { if (!window.ScrollTrigger) return; // 监听Elementor的滚动事件 window.addEventListener('scroll', this.debounce(() => { // 在滚动时刷新ScrollTrigger,确保与Elementor动画同步 ScrollTrigger.refresh(); }, 100), { passive: true }); // 监听窗口大小变化 window.addEventListener('resize', this.debounce(() => { ScrollTrigger.refresh(); }, 250)); // 在Elementor编辑模式下禁用ScrollTrigger if (this.isElementorEditMode()) { ScrollTrigger.disable(); } }, // 设置动画冲突解决方案 setupAnimationConflictResolution: function() { // 创建观察器来监听DOM变化 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { this.resolveAnimationConflicts(node); } }); } }); }); // 开始观察 observer.observe(document.body, { childList: true, subtree: true }); }, // 解决动画冲突 resolveAnimationConflicts: function(element) { // 检查元素是否同时有Elementor和GSAP动画 const hasElementorAnim = element.hasAttribute('data-has-elementor-animation') || element.classList.contains('elementor-invisible'); const hasGSAPAnim = element.hasAttribute('data-gsap-initialized'); if (hasElementorAnim && hasGSAPAnim) { // 优先使用Elementor动画,暂停GSAP动画 gsap.killTweensOf(element); // 等待Elementor动画完成后再启用GSAP setTimeout(() => { this.initGSAPForElement(element); }, 1000); } }, // 检查是否在Elementor编辑模式 isElementorEditMode: function() { return window.elementorFrontend && window.elementorFrontend.isEditMode(); }, // 防抖函数 debounce: function(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); } }, // 全局动画管理器 setupGlobalAnimationManager: function() { // 创建全局动画管理器 window.GSAPAnimationManager = { activeAnimations: new Map(), // 注册动画 register: function(id, animation) { this.activeAnimations.set(id, animation); }, // 暂停所有动画 pauseAll: function() { this.activeAnimations.forEach(animation => { if (animation && animation.pause) { animation.pause(); } }); }, // 恢复所有动画 resumeAll: function() { this.activeAnimations.forEach(animation => { if (animation && animation.resume) { animation.resume(); } }); }, // 清理动画 cleanup: function(id) { const animation = this.activeAnimations.get(id); if (animation && animation.kill) { animation.kill(); } this.activeAnimations.delete(id); } }; // 监听页面可见性变化 document.addEventListener('visibilitychange', () => { if (document.hidden) { window.GSAPAnimationManager.pauseAll(); } else { window.GSAPAnimationManager.resumeAll(); } }); }, // 公共API方法 api: { // 安全地创建GSAP动画 createAnimation: function(target, vars, options = {}) { if (!window.gsap) { console.warn('GSAP未加载,无法创建动画'); return null; } const element = typeof target === 'string' ? document.querySelector(target) : target; if (!element) { console.warn('目标元素未找到:', target); return null; } // 检查是否有Elementor动画冲突 if (element.hasAttribute('data-has-elementor-animation') || element.classList.contains('elementor-invisible')) { console.warn('元素有Elementor动画,延迟GSAP动画'); return new Promise((resolve) => { setTimeout(() => { const animation = gsap.to(element, vars); if (window.GSAPAnimationManager && options.id) { window.GSAPAnimationManager.register(options.id, animation); } resolve(animation); }, options.delay || 500); }); } const animation = gsap.to(element, vars); if (window.GSAPAnimationManager && options.id) { window.GSAPAnimationManager.register(options.id, animation); } return animation; }, // 安全地创建ScrollTrigger createScrollTrigger: function(config) { if (!window.ScrollTrigger) { console.warn('ScrollTrigger未加载'); return null; } if (GSAPElementorCompatibility.isElementorEditMode()) { console.warn('Elementor编辑模式下跳过ScrollTrigger创建'); return null; } // 添加默认配置 const defaultConfig = { refreshPriority: 1, invalidateOnRefresh: true }; const finalConfig = Object.assign({}, defaultConfig, config); try { return ScrollTrigger.create(finalConfig); } catch (error) { console.error('ScrollTrigger创建失败:', error); return null; } }, // 刷新所有动画 refresh: function() { try { if (window.ScrollTrigger) { ScrollTrigger.refresh(); } // 触发Elementor的刷新 if (window.elementorFrontend && window.jQuery) { window.jQuery(window).trigger('resize'); } console.log('动画刷新完成'); } catch (error) { console.error('动画刷新失败:', error); } }, // 检查兼容性状态 getCompatibilityStatus: function() { return { gsapLoaded: !!window.gsap, scrollTriggerLoaded: !!window.ScrollTrigger, elementorLoaded: !!window.elementorFrontend, compatibilityInitialized: GSAPElementorCompatibility.initialized, isEditMode: GSAPElementorCompatibility.isElementorEditMode() }; } } }; // 等待DOM加载完成后初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => GSAPElementorCompatibility.init()); } else { GSAPElementorCompatibility.init(); } // 暴露API到全局作用域 window.GSAPElementorCompatibility = GSAPElementorCompatibility; window.GSAPElementorAPI = GSAPElementorCompatibility.api; })();// Updated at Wed Oct 15 04:15:42 AM CST 2025