快速悬停时jQuery animate()序列乱序

Posted

技术标签:

【中文标题】快速悬停时jQuery animate()序列乱序【英文标题】:jQuery animate() Sequence Out of Order when Hovering Speedily 【发布时间】:2018-03-23 04:37:28 【问题描述】:

我用 jQuery 创建了一个动画,它按顺序(反向)在文本行中滑动。它非常简单,并且在悬停一次时效果很好。但是,当快速移动鼠标时,线条将以看似随机的顺序进行动画处理。

请参阅下面的 GIF 进行演示。第一个悬停是动画的外观。在那次悬停之后,我将鼠标移入和移出以演示文本行随机动画的问题。

请看下面我的代码示例:

HTML

<div class="image-block">
    <p>Text Line 1</p>
    <p>Text Line 2</p>
    <p>Text Line 3</p>
    <p>Text Line 4</p>
    <p>Text Line 5</p>
</div>

CSS

/* Hide text lines to begin with */
.image-block 
    position: relative;
    overflow: hidden;
    background-image: url('background-image.png');

.image-block p 
    position: absolute;
    left: -120%

jQuery

jQuery(document).ready(function() 
    // Animate text lines on hover with CSS 'left'.
    jQuery('.image-block').hover(function() 
        jQuery.fn.reverse = [].reverse;
        time = 0;
        speed = 300;
        jQuery(this).find('p').reverse().each(function() 
            jQuery(this).stop(true).delay(time).animate(
                left: '0'
            , speed,
            function() 
                jQuery(this).stop(true).delay(time).animate(
                    left: '0'
                , speed);
            )
            time = time + 125;
            speed = speed - 25;
        );
    , function() 
        // Animate text lines on hover release with CSS 'left'.
        jQuery(this).find('p').reverse().each(function() 
            jQuery(this).stop(true).animate(
                left: '-120%'
            , 150)
        );
    );
);

如何在快速移动鼠标时让前两行首先动画?释放悬停后,我是否需要以某种方式重置动画?我在动画中添加了stop(true),但这并没有解决问题。

提前谢谢你。

【问题讨论】:

一个小技巧,这种动画可能用 CSS 比 jQuery 更容易做 你不是已经问了吗?我似乎记得这个 gif。 【参考方案1】:

这也让我摸不着头脑。正如我之前解决过的那样,但为了解释起见,必须详细说明。

问题在于您在动画中使用的.delay() 方法。为动画添加延迟时,无法清除。因此,当您非常快地悬停/悬停时,之前悬停事件的处理程序不会被清除,并且一些 p 标记的动画会乱序。有关.delay() 的详细说明,请在此处查看所选答案*** 或更好的jQuery delay

关于您的问题的解决方案。您可以使用setTimeout 代替delay。我已将此 jsfiddle 作为解决方法,以使用 setTimeout 解决您的问题。

您可以通过setTimeout 做到这一点:

jQuery(document).ready(function() 
  // Animate text lines on hover with CSS 'left'.

  // To store setTimeout response
  var animations = new Array(5);

  jQuery('.image-block').hover(function() 
    jQuery.fn.reverse = [].reverse;
    time = 0;
    speed = 300;
    jQuery(this).find('p').reverse().each(function(index, item) 
            // Clear previous handlers
        clearTimeout(animations[index]);

        // Set new handlers and add to `animations`
        animations[index] = setTimeout(function()
          jQuery(item).stop(true).animate(
            left: '0'
          , speed);
        , time);

        time = time + 125;
        speed = speed - 25;
    );

  , function() 
    // Animate text lines on hover release with CSS 'left'.
    jQuery(this).find('p').each(function(index, item) 
            // Clear previous handlers
        clearTimeout(animations[index]);

        jQuery(item).stop(true).animate(
          left: '-120%'
        , 150);
    );
  );
);

在为悬停(MouseIn)添加动画时需要将setTimeout的返回值保存到一个变量中,以便在MouseOut时清除这些值。如果您需要更多关于小提琴的解释,请回复。

更新: .clearQueue() 实际上并不需要,因此删除它并更新小提琴代码。

【讨论】:

哇,非常感谢。我将对此进行测试,并以正确的答案标记回复您:)

以上是关于快速悬停时jQuery animate()序列乱序的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery .animate() 时的图像动画问题

在悬停时使用 jQuery .animate 显示新的 div

jquery animate 在鼠标悬停时不起作用[关闭]

jQuery - fadeIn()、fadeOut()、animate()、stop() 和闪烁

JQuery Animate - 如何在悬停后立即停止悬停功能(不要完成悬停功能)

Jquery Animate 背景图像在悬停时摇摆在 Firefox 中不起作用