简体   繁体   English

在视口中可见时,在链中延迟CSS动画

[英]Delay CSS animations in chain, when visible on viewport

I have this jfiddle where: 我有这个jfiddle

  1. CSS animation starts when the div is on viewport. div在视口上时,CSS动画开始。
  2. I have an unknown number of div with an Icon, and 2 text lines. 我有一个未知数量的div带有一个Icon和2个文本行。

What I need: 我需要的:

  1. Each icon animated with a delay, with respect to the next one. 相对于下一个图标,每个图标都会延迟动画。 In my jsfiddle all icons are animated simultaneously. 在我的jsfiddle中,所有图标都是同时动画的。

  2. The actual program might have 1, 2, or 300 divs with an icon, the solution must work for any number, not only with the 3 items of my jsfiddle example. 实际程序可能有1,2或300个带图标的divs ,解决方案必须适用于任何数字,而不仅仅是我的jsfiddle示例的3个项目。

  3. I have bootstrap on divs , and with the scroll control, the animation only starts if the div appears on viewport, whilst on a notebook I get displayed 6 icons in a row, on a smartphone only 1. 我有divs bootstrap,并且使用滚动控件,动画只在div出现在视口上时启动,而在笔记本上我会连续显示6个图标,仅在智能手机上显示1。

var $animation_elements = $('.animation-element');
var $window = $(window);

function check_if_in_view() {
    var window_height = $window.height();
    var window_top_position = $window.scrollTop();
    var window_bottom_position = (window_top_position + window_height + 15);

    $.each($animation_elements, function() {
        var $element = $(this);
        var element_height = $element.outerHeight();
        var element_top_position = $element.offset().top;
        var element_bottom_position = (element_top_position + element_height);

        //check to see if this current container is within viewport
        if ((element_bottom_position >= window_top_position) &&
           (element_top_position <= window_bottom_position)) {
              $element.addClass('in-view');
        else {
              $element.removeClass('in-view');
    }
});
$window.on('scroll resize', check_if_in_view);
$window.trigger('scroll'); 
  1. The function to set a delayed action in JavaScript is setTimeout() , with it you can set one(in this case) delayed action per element (each iteration). 在JavaScript中设置延迟操作的函数是setTimeout() ,使用它可以为每个元素设置一个(在这种情况下)延迟操作(每次迭代)。 However inside for loops, you cannot access to external variables in realtime inside setTimeout(), so you need to do it through a closure ( ref1 , ref2 ): 但是在for循环中,你无法在setTimeout()内实时访问外部变量,所以你需要通过一个闭包( ref1ref2 )来实现:

     (function(delay, $element, savedtimeout) { // 'savedtimeout'(alias of timeouts) is accessible. // but 'timeouts'(external var) is not accessible in realtime. savedtimeout[i][0] = setTimeout(function() { //Start animation $element.removeClass('paused'); countInView--; }, delay, timeouts); })(delay, $element, timeouts); 

    In order to delete a delayed action for a specific icon, you have to assign its returning ID to a variable, then you can interrupt its execution with the given ID using removeTimeout(ID) : 为了删除特定图标的延迟操作,您必须将其返回的ID分配给变量,然后您可以使用removeTimeout(ID)使用给定的ID中断其执行:

     timeouts[i][0] = setTimeout(); // Returns an unique ID clearTimeout(timeouts[i][0]); 
    • You can check my other post to see how to manage and save a timeout ID for each icon. 您可以查看我的其他帖子 ,了解如何管理和保存每个图标的超时ID。
    • The function you are using $.each cannot be reset to 0 its index, so it gives much less options for future implementations. 您使用$.each的函数无法重置为其索引0 ,因此它为将来的实现提供了更少的选项。 I would rather replace with a for loop, taking advantage of its index. 我宁愿用for循环替换它,利用它的索引。
  2. The more you narrow the div width, the more divs your smartphone will be able to display. 缩小div宽度越多,智能手机能够显示的div就越多。 So you have to prefix the width, otherwise it seems like each div will cover all the width on your device's screen: 所以你必须为宽度添加前缀,否则看起来每个div都将覆盖设备屏幕上的所有宽度:

     .slide-left { width: 150px; /* eg */ } 

Altogether solution : https://jsfiddle.net/quq2q9cg/ 完全解决方案https//jsfiddle.net/quq2q9cg/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM