主页/jQuery教程/动画与特效/jQuery动画队列与控制

jQuery动画队列与控制

7,141字
30–45 分钟

概览

目录

jQuery的动画队列机制是管理多个连续动画的核心。所有通过animate()fadeIn()等方法触发的动画,默认都会被添加到一个名为“fx”的标准队列中,并按照先进先出的顺序依次执行。本章节将深入探讨如何查看、操作和控制这些队列,包括使用queue()dequeue()方法管理自定义队列,以及利用clearQueue()stop()finish()delay()等方法对动画执行过程进行精确干预。理解并掌握这些jQuery动画队列jQuery动画控制技术,是构建复杂、流畅且用户友好的交互效果的前提。

queue() 与 dequeue():队列的基石

queue()方法用于显示或操作在匹配元素上已经执行的函数队列。dequeue()则用于执行队列中的下一个函数。这两个方法是实现jQuery动画队列自定义控制的基础。

queue()

语法

// 显示匹配元素上的函数队列
.queue( [queueName] )

// 在匹配元素上操作函数队列
.queue( [queueName], newQueue )
.queue( [queueName], callback( next ) )
  • queueName(可选):一个字符串,代表队列的名称。默认为 "fx",即标准的动画队列。
  • newQueue:一个由函数组成的数组,用以替换现有的队列。
  • callback( next ):一个回调函数,会被添加到队列中。在该函数内部,必须调用next()以便继续执行队列中的下一个函数。

dequeue()

语法

.dequeue( [queueName] )
  • queueName(可选):一个字符串,代表要执行的队列名称。默认为 "fx"

示例:自定义队列

以下示例展示了如何创建一个非动画的自定义队列,并手动控制其执行流程。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>queue 与 dequeue 示例</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .box { width: 100px; height: 100px; background: #3498db; margin: 20px; display: none; }
        button { margin: 5px; }
    </style>
</head>
<body>
    <button id="start">开始自定义队列</button>
    <div class="box"></div>
    <script>
        var $box = $('.box');

        function showBox(next) {
            $box.show(500, next);
        }

        function changeColor(next) {
            $box.css('background-color', '#e74c3c');
            setTimeout(next, 500);
        }

        function hideBox(next) {
            $box.hide(500, next);
        }

        $('#start').on('click', function() {
            // 清空原有队列,并将自定义函数添加到队列
            $box.queue([]); // 清空队列
            $box.queue(showBox);
            $box.queue(changeColor);
            $box.queue(hideBox);

            // 启动队列
            $box.dequeue();
        });
    </script>
</body>
</html>

在这个例子中,通过queue()将三个函数依次添加到队列,然后通过dequeue()启动第一个函数。每个函数在执行完毕后,必须调用作为参数传入的next函数,才能驱动队列继续执行下一个函数,这体现了jQuery动画控制中手动管理队列流程的核心思想。

clearQueue():清空未执行的队列

clearQueue()方法用于移除队列中尚未运行的所有项目。当需要阻止一系列待执行的动画时,此方法非常有用。

语法

.clearQueue( [queueName] )
  • queueName(可选):一个字符串,代表要清空的队列名称。默认为 "fx",即标准的动画队列。

示例:阻止后续动画

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>clearQueue 示例</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .box { width: 100px; height: 100px; background: #2ecc71; position: absolute; }
        button { margin: 5px; }
    </style>
</head>
<body>
    <button id="animate">开始动画序列</button>
    <button id="clear">清空队列</button>
    <div class="box"></div>
    <script>
        var $box = $('.box');

        $('#animate').on('click', function() {
            $box
                .animate({ left: '+=200' }, 1000)
                .animate({ top: '+=200' }, 1000)
                .animate({ left: '-=200' }, 1000)
                .animate({ top: '-=200' }, 1000);
        });

        $('#clear').on('click', function() {
            // 清空动画队列,阻止后续动画执行
            $box.clearQueue();
        });
    </script>
</body>
</html>

当点击“开始动画序列”后,盒子会执行一个正方形的运动轨迹。如果在动画执行过程中点击“清空队列”,clearQueue()会移除队列中尚未执行的动画,盒子会立即停止在当前状态。这是jQuery动画控制中用于中断未开始动画的关键手段。

stop() 与 finish():停止当前动画

stop()finish()都用于停止当前正在运行的动画,但它们的行为有显著区别,是实现精细jQuery动画控制的重要工具。

语法

.stop( [clearQueue] [, jumpToEnd] )
.finish( [queue] )
  • clearQueue(布尔值):指示是否清空队列中后续的动画。true表示清空,false(默认值)表示不清空。
  • jumpToEnd(布尔值):指示是否立即完成当前动画。true表示立即跳到当前动画的最终状态,false(默认值)表示停留在当前状态。
  • queue(字符串):要完成动画的队列名称。默认为 "fx"
特性.stop(clearQueue, jumpToEnd).finish()
停止当前动画
清空后续队列clearQueue 参数控制 (默认 false)是,立即清空并完成所有队列中的动画
处理当前动画jumpToEnd 参数控制 (默认 false,停在当前帧)强制当前动画立即跳到最终状态
处理队列动画不影响队列中后续动画(除非 clearQueuetrue)强制队列中所有动画立即跳到其最终状态

示例:stop() 与 finish() 对比

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>stop 与 finish 对比</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .box { width: 100px; height: 100px; background: #f39c12; position: absolute; top: 50px; }
        button { margin: 5px; }
    </style>
</head>
<body>
    <button id="animate">开始动画</button>
    <button id="stop">stop()</button>
    <button id="finish">finish()</button>
    <div class="box"></div>
    <script>
        var $box = $('.box');

        $('#animate').on('click', function() {
            $box
                .animate({ left: '+=400' }, 3000)
                .animate({ top: '+=100' }, 1000)
                .animate({ left: '-=400' }, 3000);
        });

        $('#stop').on('click', function() {
            // 停止当前动画,不清空队列,停在当前帧
            $box.stop();
        });

        $('#finish').on('click', function() {
            // 立即完成所有动画
            $box.finish();
        });
    </script>
</body>
</html>

运行示例,在第一个动画执行中点击stop(),盒子会停在当前位置,后续动画(改变top和左移)仍会执行。而点击finish(),盒子会瞬间完成所有排队动画,直接到达最终位置(左移400px、上移100px后的坐标)。这个对比清晰地展示了两种方法在jQuery动画控制中的不同应用场景。

delay():设置延迟

delay()方法用于设置一个定时器,以延迟队列中后续项目的执行。它常用于在连续动画之间添加停顿。

语法

.delay( duration [, queueName ] )
  • duration:一个整数,指定延迟的时间,单位是毫秒。
  • queueName(可选):一个字符串,代表将在其上执行延迟的队列的名称。默认为 "fx"

示例:动画间的停顿

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>delay 示例</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .box { width: 100px; height: 100px; background: #9b59b6; position: absolute; }
        button { margin: 5px; }
    </style>
</head>
<body>
    <button id="animate">带延迟的动画</button>
    <div class="box"></div>
    <script>
        var $box = $('.box');

        $('#animate').on('click', function() {
            $box
                .animate({ left: '+=200' }, 600)
                .delay(1000) // 停顿1秒
                .animate({ top: '+=200' }, 600)
                .delay(1000)
                .animate({ left: '-=200' }, 600);
        });
    </script>
</body>
</html>

此示例中,盒子每次移动后都会停顿1秒,然后再开始下一段移动。delay()方法让创建这种带有间歇的动画序列变得非常简单,是jQuery动画队列控制中用于实现时间间隔的标准方式。

综合示例:可控制的幻灯片

以下综合示例将上述多个动画控制方法整合到一个简单的幻灯片组件中,演示了如何在实际场景中运用jQuery动画队列jQuery动画控制

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>可控制的幻灯片 - 综合示例</title>
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <style>
        .slider { width: 400px; height: 300px; border: 2px solid #ccc; overflow: hidden; position: relative; margin: 20px 0; }
        .slider ul { list-style: none; padding: 0; margin: 0; width: 2000px; position: relative; }
        .slider li { float: left; width: 400px; height: 300px; background-size: cover; background-position: center; color: white; font-size: 3em; text-align: center; line-height: 300px; }
        .slider li:nth-child(1) { background-color: #e74c3c; }
        .slider li:nth-child(2) { background-color: #8e44ad; }
        .slider li:nth-child(3) { background-color: #2980b9; }
        .controls { margin-top: 10px; }
        .controls button { margin-right: 5px; }
    </style>
</head>
<body>
    <div class="slider">
        <ul>
            <li>1</li>
            <li>2</li>
            <li>3</li>
        </ul>
    </div>
    <div class="controls">
        <button id="next">下一张</button>
        <button id="prev">上一张</button>
        <button id="stopSlide">停止当前</button>
        <button id="clearQueue">清空队列</button>
        <button id="finishNow">立即完成</button>
    </div>

    <script>
        var $sliderUl = $('.slider ul');
        var slideWidth = $('.slider').width();
        var currentIndex = 0;
        var totalSlides = $('.slider li').length;

        function moveToSlide(index) {
            // 停止当前动画,并清空后续队列,防止快速点击造成动画累积
            $sliderUl.stop(true, false).animate({
                left: -index * slideWidth
            }, 500);
            currentIndex = index;
        }

        $('#next').on('click', function() {
            var nextIndex = (currentIndex + 1) % totalSlides;
            moveToSlide(nextIndex);
        });

        $('#prev').on('click', function() {
            var prevIndex = (currentIndex - 1 + totalSlides) % totalSlides;
            moveToSlide(prevIndex);
        });

        $('#stopSlide').on('click', function() {
            // 停止当前动画,但不清空队列,停在当前帧
            $sliderUl.stop();
        });

        $('#clearQueue').on('click', function() {
            // 清空动画队列,移除后续动画
            $sliderUl.clearQueue();
        });

        $('#finishNow').on('click', function() {
            // 立即完成所有动画,跳到目标位置
            $sliderUl.finish();
        });
    </script>
</body>
</html>

在这个幻灯片示例中,moveToSlide函数通过stop(true, false)确保了在快速点击“下一张”时,前一个动画被立即停止并清空其后续队列,从而防止了动画的过度累积和延迟。旁边的控制按钮则分别演示了stop()clearQueue()finish()在真实交互场景下的作用,完整地展现了jQuery动画控制API的强大与灵活。

版本变更记录

版本变更内容
1.0引入基础的动画队列机制,包含 queuedequeue
1.2引入 stop() 方法。
1.4引入 delay() 方法。
1.6引入 finish() 方法。
4.0移除 jQuery.fx.interval API。

浏览器兼容性

jQuery核心的动画队列与控制方法在现代浏览器中拥有极佳的兼容性。以下为关键方法的最低支持版本概览。

浏览器版本
Chrome30+
Edge12+
Firefox25+
Opera18+
Safari7+
Chrome Android30+
Firefox for Android25+
Opera Android18+
Safari on iOS7+
Samsung Internet4.0+
WebView Android4.4+
WebView on iOS7+

注:以上兼容性数据基于jQuery 3.x及4.x版本的主流支持范围。对于更早期的浏览器版本(如IE6-8),jQuery 1.x和2.x提供了有限的兼容性支持,但动画效果的性能和稳定性可能无法得到保证。

掌握jQuery动画队列jQuery动画控制,是超越简单动画调用,实现复杂、高效且用户体验良好的动态效果的关键。通过灵活运用queue()stop()finish()delay()clearQueue()等核心方法,开发者能够精确编排动画流程,有效避免性能陷阱,并赋予用户对界面交互相应的控制权,从而构建出专业水准的Web交互应用。