如何将多场景按钮的jQuery单独点击函数简化为通用逻辑?
简化场景切换的jQuery代码实现方案
问题背景
现有6个带通用类.scene及独立类.scene1至.scene6的场景元素,每个场景内包含带通用类.b及独立类.b1至.b6的按钮。点击按钮时,对应场景需缩放至全屏(top、left设为0,宽高100%),其余场景按固定方向移出屏幕。目前为每个按钮单独编写点击函数,示例代码如下:
$('.b3').click(function(){ $('.scene1').delay(200).animate({'left':'100%'}, 1400, 'easeInOutCubic').delay(200).fadeOut(1200); $('.scene2').delay(200).animate({'left':'-100%'}, 1400, 'easeInOutCubic').delay(200).fadeOut(1200); $('.scene3').delay(200).animate({'top':0,'left':0,'width':'100%','height':'100%'}, 3000, 'easeInOutCubic'); $('.scene4').delay(300).animate({'top':'150%'}, 1400, 'easeInOutCubic').delay(200).fadeOut(1200); $('.scene5').delay(250).animate({'left':'-100%'}, 1400, 'easeInOutCubic').delay(200).fadeOut(1200); $('.scene6').delay(200).animate({'left':'-100%'}, 1400, 'easeInOutCubic').delay(200).fadeOut(1200); });
希望将所有逻辑统一在通用类.b的点击函数下,而非为每个按钮单独声明。用户尝试的多条件判断代码存在语法错误,HTML结构如下:
<main> <section class="scene scene1"> <div class="b b1"></div> </section> <section class="scene scene2"> <div class="b b2"></div> </section> <!-- 其余scene3至scene6结构类似 --> </main>
原尝试代码的错误点
hasClass()参数错误:方法内不需要加.,正确写法是hasClass('scene1'),加.会导致无法匹配类名- 条件判断语法错误:
else后不能直接跟else if,违反JavaScript语法规则,会直接报错 - 逻辑冗余:循环所有
.scene元素并逐个判断的写法完全没必要,重复执行大量无效判断
正确简化实现方案
我们可以通过配置化+通用逻辑的方式实现,既消除重复代码,又方便后期维护:
步骤1:定义动画配置对象
将每个场景对应的动画参数(目标场景的全屏动画、其他场景的移出动画)集中存放,修改动画参数时直接改配置即可:
// 每个场景的动画配置,key为场景编号,value包含目标场景和其他场景的动画规则 const sceneAnimConfig = { 1: { targetAnim: { delay: 200, props: {top:0, left:0, width:'100%', height:'100%'}, duration: 3000, easing: 'easeInOutCubic' }, others: { 2: { delay:200, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' }, 3: { delay:300, props:{top:'150%'}, duration:1400, easing:'easeInOutCubic' }, 4: { delay:300, props:{top:'150%'}, duration:1400, easing:'easeInOutCubic' }, 5: { delay:250, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' }, 6: { delay:200, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' } } }, 2: { targetAnim: { delay:200, props: {top:0, left:0, width:'100%', height:'100%'}, duration: 3000, easing: 'easeInOutCubic' }, others: { 1: { delay:200, props:{left:'100%'}, duration:1400, easing:'easeInOutCubic' }, 3: { delay:300, props:{top:'150%'}, duration:1400, easing:'easeInOutCubic' }, 4: { delay:300, props:{top:'150%'}, duration:1400, easing:'easeInOutCubic' }, 5: { delay:250, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' }, 6: { delay:200, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' } } }, 3: { targetAnim: { delay:200, props: {top:0, left:0, width:'100%', height:'100%'}, duration: 3000, easing: 'easeInOutCubic' }, others: { 1: { delay:200, props:{left:'100%'}, duration:1400, easing:'easeInOutCubic' }, 2: { delay:200, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' }, 4: { delay:300, props:{top:'150%'}, duration:1400, easing:'easeInOutCubic' }, 5: { delay:250, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' }, 6: { delay:200, props:{left:'-100%'}, duration:1400, easing:'easeInOutCubic' } } }, // 请根据原代码补充scene4、scene5、scene6的配置,参数对应原按钮函数中的设置即可 4: { /* ... */ }, 5: { /* ... */ }, 6: { /* ... */ } };
步骤2:编写通用点击事件处理函数
通过通用逻辑匹配当前按钮对应的场景,再根据配置执行动画:
$('.b').click(function() { // 获取当前按钮所在的场景元素 const $targetScene = $(this).closest('.scene'); // 从场景类名中提取编号(比如从scene3中取出3) const sceneNum = parseInt($targetScene.attr('class').match(/scene(\d+)/)[1]); const currentConfig = sceneAnimConfig[sceneNum]; // 执行目标场景的全屏动画 $targetScene .delay(currentConfig.targetAnim.delay) .animate(currentConfig.targetAnim.props, currentConfig.targetAnim.duration, currentConfig.targetAnim.easing); // 执行其余场景的移出动画 $('.scene').not($targetScene).each(function() { const otherSceneNum = parseInt($(this).attr('class').match(/scene(\d+)/)[1]); const otherAnimConfig = currentConfig.others[otherSceneNum]; $(this) .delay(otherAnimConfig.delay) .animate(otherAnimConfig.props, otherAnimConfig.duration, otherAnimConfig.easing) .delay(200) .fadeOut(1200); }); });
方案优势
- 可维护性强:所有动画参数集中在配置对象中,修改动画延迟、方向、时长无需改动逻辑代码
- 通用性高:不管场景数量增加还是减少,只需修改配置对象即可适配
- 代码简洁:消除了大量重复的点击事件函数,所有按钮共用同一个处理逻辑
内容的提问来源于stack exchange,提问作者Igor Laszlo
相关产品推荐
相关产品推荐

