display:none元素展开后CSS动画全触发 如何仅滚动到视口时播放
问题原因
你遇到的动画同时触发的问题根源在于:
页面加载时触发了一次scroll事件执行动画判断逻辑,此时隐藏区域(id为hide的元素)是display: none状态,该区域内的动画元素偏移量计算结果为0,默认满足进入视口的判定条件,直接被替换成了animated类。只是因为父级元素隐藏,动画不可见,当你点击按钮展开隐藏区域时,这些元素已经处于动画触发状态,所以会同时播放。
解决步骤
- 给动画判断逻辑增加可见性校验,不可见的元素直接跳过处理
- 收起隐藏区域时重置该区域内的动画元素状态,方便下次展开时正常触发动画
修改后的完整代码
JS代码
function see_more(){ document.getElementById("hide").style.display = 'block'; document.getElementById("seeMore").style.display = 'none'; document.getElementById("seeLess").style.display = 'block'; } function see_less(){ document.getElementById("hide").style.display = 'none'; document.getElementById("seeMore").style.display = 'block'; document.getElementById("seeLess").style.display = 'none'; // 重置隐藏区域内的动画元素状态,下次展开可重新触发 $('#hide .animated').removeClass('animated').addClass('animatable'); } jQuery(function($) { var doAnimations = function() { var offset = $(window).scrollTop() + $(window).height(), $animatables = $('.animatable'); if ($animatables.length == 0) { $(window).off('scroll', doAnimations); } $animatables.each(function(i) { $animatable = $(this); // 新增校验:元素不可见则跳过处理 if (!$animatable.is(':visible')) return; if (($animatable.offset().top + $animatable.height() +65) < offset) { $animatable.removeClass('animatable').addClass('animated'); } }); }; $(window).on('scroll', doAnimations); $(window).trigger('scroll'); });
原有CSS和HTML代码无需修改,保留即可。修改后展开隐藏区域时,只有当前处于视口内的元素会触发动画,其余元素需要等用户滚动到对应位置才会触发,符合预期效果。
内容的提问来源于stack exchange,提问作者gears244
相关产品推荐
相关产品推荐

