如何使用JQuery链接或排队自定义函数?

时间:2009-07-07 22:54:19

标签: jquery animation queue chaining

我有多个函数可以对HTML的不同部分执行不同的动画。我想链接或排队这些函数,以便它们按顺序而不是同时运行动画。

我试图按顺序自动化多个事件,看起来像用户点击了不同的按钮或链接。

我可以使用回调函数执行此操作,但之后我必须从不同的函数中提取所有动画并以正确的模式重新组合。

jquery“队列”有帮助吗?我无法理解队列的documentation

示例,JQuery:

 function One() {
        $('div#animateTest1').animate({ left: '+=200' }, 2000);
    }
    function Two() {
        $('div#animateTest2').animate({ width: '+=200' }, 2000);
    }

// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
    One();
    Two();

HTML:

    <div id="animatetest" style="width:50px;height:50px;background-color:Aqua;position:absolute;"></div>
    <div id="animatetest2" style="width:50px;height:50px;background-color:red;position:absolute;top:100px;"></div>

感谢。

编辑: 我用timers尝试过,但我认为有更好的方法可以做到。

编辑#2:

让我更具体一点。我有多个功能绑定到&amp;将事件悬停在页面的不同元素上。通常这些功能彼此无关(它们不相互引用)。我想模拟用户在不更改现有函数代码的情况下完成这些事件。

15 个答案:

答案 0 :(得分:37)

jQuery Queue代码没有尽可能详细记录,但基本思路是:

$("#some_element").queue("namedQueue", function() {
  console.log("First");
  var self = this;
  setTimeout(function() {
    $(self).dequeue("namedQueue");
  }, 1000);
});

$("#some_element").queue("namedQueue", function() {
  console.log("Second");
  var self = this;
  setTimeout(function() {
    $(self).dequeue("namedQueue");
  }, 1000);
});

$("#some_element").queue("namedQueue", function() {
  console.log("Third");
});

$("#some_element").dequeue("namedQueue");

如果运行此代码,您将在控制台中看到“First”,暂停1秒,在控制台中看到“Second”,另一个暂停1秒,最后在控制台中看到“Third”。

基本思想是你可以将任意数量的命名队列绑定到一个元素。您可以通过调用dequeue从队列中删除元素。您可以根据需要自己手动执行此操作,但如果您希望队列自动运行,则只需在排队功能中调用dequeue即可。

jQuery中的动画都在名为fx的队列中运行。为元素设置动画时,如果当前没有动画正在运行,它会自动在队列中添加新动画并调用dequeue。如果您愿意,可以将自己的回调插入fx队列;您只需要在末尾手动调用dequeue(与任何其他队列一样使用)。

答案 1 :(得分:3)

我创建了一个函数数组,并添加了要排队的所有函数。

然后我会附加一个函数调用,它循环遍历数组并通过jQuery调用每个函数到事件。

您可以为jQuery创建一个非常简单的插件,它也可以在内部处理它。

答案 2 :(得分:2)

假设您要将OneTwo作为单独的函数, 你可以这样做:

function One(callback) {
    $('div#animateTest1').animate({ left: '+=200' }, 2000, 
        function(e) { callback(); });
}
function Two() {
    $('div#animateTest2').animate({ width: '+=200' }, 2000);
}

// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
    One(Two);

答案 3 :(得分:2)

我会将第二个作为回调函数运行:

$('div#animateTest1').animate({ left: '+=200' }, 2000, function(){
    two();
});

当第一个动画结束时会运行两个(),如果你在定时队列上有更多动画,我会使用jquery timer plugin代替setTimeout(),这在某些情况下非常方便。

答案 4 :(得分:2)

在我的一个Web项目中,我必须根据触发的事件执行各种操作序列。我使用回调(类似访问者模式)来做到这一点。我创建了一个对象来包装任何函数或一组操作。然后我会排队那些包装纸;数组运行正常。当事件被触发时,我将迭代数组,调用我的对象的专门方法进行回调。该回调触发了我的迭代继续。

要包装函数,您需要the apply function的知识。 apply函数接受范围的对象和参数数组。这样你就不需要了解你正在包装的功能。

答案 5 :(得分:2)

只是喜欢什么?

var f1 = function() {return $(SELECTOR1).animate({ 'prop': 'value' }, 1000)};
var f2 = function() {return $(SELECTOR2).animate({ 'prop': 'value' }, 1000)};
var f3 = function() {return $(SELECTOR3).animate({ 'prop': 'value' }, 1000)};

$.when(f1).then(f2).then(f3);

答案 6 :(得分:1)

更安全且100%的工作方式是使用变量和if分支。 在下面的示例中,我们执行4个作业,这需要1秒钟,在作业之后我们希望函数f2运行。

<html><body>
<div id="a" class="a" />
 <script type="text/javascript">
var jobs = 0;
function f1() {
job(); 
job();
job();
job();    
};

function f2() {
    if(jobs >3)
        l("f2");
};

<!------------------------- ->
function job() {
    setTimeout(function() {
        l("j");
        jobs+=1;
        f2();
    }, 1000);
}
function l(a) {
    document.getElementById('a').innerHTML+=a+"<br />";
};
f1();


</script></body></html>

答案 7 :(得分:1)

非常简单的修复。

function One() {
        $('div#animateTest1').animate({ left: '+=200' }, 2000, Two);
    }
    function Two() {
        $('div#animateTest2').animate({ width: '+=200' }, 2000);
    }

// Call these functions sequentially so that the animations
// in One() run b/f the animations in Two()
    One();
//We no longer need to call Two, as it will be called when 1 is completed.
    //Two();

答案 8 :(得分:0)

对于已经在2000毫秒内定义的动画间隔,您可以在2000毫秒内进行第二次延迟呼叫:

One();
SetTimeout(function(){
  Two();
}, 2000);

答案 9 :(得分:0)

如果回调为null,以下内容将起作用并且不会出错:

function One(callback)
{
    $('div#animateTest1').animate({ left: '+=200' }, 2000, 
       function()
       {
            if(callback != null)
            {
                 callback();
            }
       }
    );
}
function Two()
{
    $('div#animateTest2').animate({ width: '+=200' }, 2000);
}

var callback = function(){ Two(); };
One(callback);

答案 10 :(得分:0)

@TrippRitter必须将.call附加到回调

One = function(callback){
    $('div#animateTest1').animate({ left: '+=200' }, 2000, function(){
        if(typeof callback == 'function'){
            callback.call(this);
        }
    });
}

Two = function(){
    $('div#animateTest2').animate({ width: '+=200' }, 2000);
}

One(function(){ 
    Two();
});

但它与执行以下操作相同

$('div#animateTest1')
    .animate({ left: '+=200' }, 2000, 
    function(){
       Two();
    });

Two = function(){
    $('div#animateTest2').animate({ width: '+=200' }, 2000);
}

答案 11 :(得分:0)

$('div#animateTest1').animate({left: '+=200'},2000, 
function(){
   $('div#animateTest2').animate({ width: '+=200' }, 2000);
}
);

答案 12 :(得分:0)

复制并粘贴............ 2013年7月9日

<!doctype html>
<html lang="en">
    enter code here<head>
  <meta charset="utf-8">
  <title>jQuery.queue demo</title>
  <style>
  div { margin:3px; width:40px; height:40px;
        position:absolute; left:0px; top:30px;
        background:green; display:none; }
  div.newcolor { background:blue; }
    </style>
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>

  <button id="start">Start</button>
  <button id="stop">Stop</button>
  <div></div>
<script>
   $("#start").click(function () {
      $("div").show("slow");
      $("div").animate({left:'+=200'},5000);
      jQuery.queue( $("div")[0], "fx", function () {
        $(this).addClass("newcolor");
        jQuery.dequeue( this );
      });
      $("div").animate({left:'-=200'},1500);
      jQuery.queue( $("div")[0], "fx", function () {
        $(this).removeClass("newcolor");
        jQuery.dequeue( this );
      });
      $("div").slideUp();
    });
    $("#stop").click(function () {
      jQuery.queue( $("div")[0], "fx", [] );
      $("div").stop();
    });
</script>

</body>
</html>

答案 13 :(得分:0)

虽然Yehuda Katz的答案在技术上是正确的,但它会在更大的更复杂的动画中迅速膨胀。

我为像你这样的情况制作了一个允许排队功能的插件(如果需要,可以暂停和恢复)。

演示:https://jessengatai.github.io/okaynowthis.js/

使用okaynowthis.js解决问题的方法如下:

$('window').load(function(){

    // keyframe 1
    $('body').okaynowthis('keyframe',0,function(){
        $('div#animateTest1').animate({ left: '+=200' }, 2000);
        // + anything else you want to do

    // keyframe 2 (with 2 seconds delay from keyframe 1)
    }).okaynowthis('keyframe',2000,function(){
        $('div#animateTest2').animate({ left: '+=200' }, 2000);
        // + anything else you want to do

    });

});

答案 14 :(得分:-1)

而不是创建一个简单的函数方法:

$('#main').animate({ "top": "0px"}, 3000, function()
   {    $('#navigation').animate({ "left": "100px"},  3000, function() 
        {
            alert("Call after first and second animation is completed.");
        })
    }
);

因此,Jquery默认提供逐个执行函数的队列。

相关问题