Вопрос по jquery – Что такое очереди в jQuery?

385

Я нашел документ jQuery.com наqueue()/dequeue() это слишком просто, чтобы понять. Что такое очереди в jQuery? Как я должен их использовать?

Хороший пример решения проблемы с очередью:stackoverflow.com/questions/5230333/… gnarf

Ваш Ответ

6   ответов
20
Multiple objects animation in a queue

Jquery позволяет нам ставить в очередь только один объект. Но внутри функции анимации мы можем получить доступ к другим объектам. В этом примере мы строим нашу очередь поверх объекта #q, анимируя объекты # box1 и # box2.

Думайте об очереди как о массиве функций. Таким образом, вы можете управлять очередью как массивом. Вы можете использовать push, pop, unshift, shift для управления очередью. В этом примере мы удаляем последнюю функцию из очереди анимации и вставляем ее в начале.

Когда мы закончим, мы запускаем очередь анимации с помощью функции dequeue ().

Смотрите на jsFiddle

HTML:

  <button id="show">Start Animation Queue</button>
  <p></p>
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="q"></div>

ЯШ:

$(function(){

 $('#q').queue('chain',function(next){  
      $("#box2").show("slow", next);
  });


  $('#q').queue('chain',function(next){  
      $('#box1').animate(
          {left: 60}, {duration:1000, queue:false, complete: next}
      )
  });    


  $('#q').queue('chain',function(next){  
      $("#box1").animate({top:',200'},1500, next);
  });


  $('#q').queue('chain',function(next){  
      $("#box2").animate({top:'200'},1500, next);
  });


  $('#q').queue('chain',function(next){  
      $("#box2").animate({left:'200'},1500, next);
  });

  //notice that show effect comes last
  $('#q').queue('chain',function(next){  
      $("#box1").show("slow", next);
  });

});

$("#show").click(function () {
    $("p").text("Queue length is: " + $('#q').queue("chain").length);

    // remove the last function from the animation queue.
    var lastFunc = $('#q').queue("chain").pop();
    // insert it at the beginning:    
    $('#q').queue("chain").unshift(lastFunc);

    //start animation queue
    $('#q').dequeue('chain');
});

CSS:

        #box1 { margin:3px; width:40px; height:40px;
                position:absolute; left:10px; top:60px; 
                background:green; display: none; }
        #box2 { margin:3px; width:40px; height:40px;
                position:absolute; left:100px; top:60px; 
                background:red; display: none; }
        p { color:red; }  
15

вместо этого

$('#my-element').animate( { opacity: 0.2, width: '100px' }, 2000);

Который затемняет элемент и делает ширину 100 пикселейat the same time, Использование очереди позволяет ставить анимацию. Так что один заканчивается за другим.

$("#show").click(function () {
    var n = $("div").queue("fx");
    $("span").text("Queue length is: " + n.length);
});

function runIt() {
    $("div").show("slow");
    $("div").animate({left:'+=200'},2000);
    $("div").slideToggle(1000);
    $("div").slideToggle("fast");
    $("div").animate({left:'-=200'},1500);
    $("div").hide("slow");
    $("div").show(1200);
    $("div").slideUp("normal", runIt);
}
runIt();

Пример изhttp://docs.jquery.com/Effects/queue

Можете ли вы продемонстрировать тот же код, используя очередь JQuery?
@SolutionYogi - Пожалуйста, измените мой ответ, если считаете, что он неправильный - ответ CW 'd, и у вас достаточно повторений.
Это не правильно. Когда у вас есть несколько «одушевленных» вызовы, jQuery помещает их в очередь, чтобы выполнить их один за другим. Используя метод очереди, теперь вы можете получить доступ к этой очереди и манипулировать ею, если это необходимо.
42

вы должны понимать, как jQuery выполняет анимацию. Если вы пишете несколько вызовов метода animate один за другим, jQuery создает «внутренний». очереди и добавляет эти вызовы методов к нему. Затем он запускает эти одушевленные звонки один за другим.

Рассмотрим следующий код.

function nonStopAnimation()
{
    //These multiple animate calls are queued to run one after
    //the other by jQuery.
    //This is the reason that nonStopAnimation method will return immeidately
    //after queuing these calls. 
    $('#box').animate({ left: '+=500'}, 4000);
    $('#box').animate({ top: '+=500'}, 4000);
    $('#box').animate({ left: '-=500'}, 4000);

    //By calling the same function at the end of last animation, we can
    //create non stop animation. 
    $('#box').animate({ top: '-=500'}, 4000 , nonStopAnimation);
}

«Очередь» / «очередь» Метод дает вам контроль над этой «очередью анимаций».

По умолчанию очередь анимации называется «fx». Я создал образец страницы здесь, который имеет различные примеры, которые иллюстрируют, как можно использовать метод очереди.

http://jsbin.com/zoluge/1/edit?html,output

Код для примера страницы выше

$(document).ready(function() {
    $('#nonStopAnimation').click(nonStopAnimation);

    $('#stopAnimationQueue').click(function() {
        //By default all animation for particular 'selector'
        //are queued in queue named 'fx'.
        //By clearning that queue, you can stop the animation.
        $('#box').queue('fx', []);
    });

    $('#addAnimation').click(function() {
        $('#box').queue(function() {
            $(this).animate({ height : '-=25'}, 2000);
            //De-queue our newly queued function so that queues
            //can keep running.
            $(this).dequeue();
        });
    });

    $('#stopAnimation').click(function() {
        $('#box').stop();
    });

    setInterval(function() {
        $('#currentQueueLength').html(
         'Current Animation Queue Length for #box ' + 
          $('#box').queue('fx').length
        );
    }, 2000);
});

function nonStopAnimation()
{
    //These multiple animate calls are queued to run one after
    //the other by jQuery.
    $('#box').animate({ left: '+=500'}, 4000);
    $('#box').animate({ top: '+=500'}, 4000);
    $('#box').animate({ left: '-=500'}, 4000);
    $('#box').animate({ top: '-=500'}, 4000, nonStopAnimation);
}

Теперь вы можете спросить, почему я должен беспокоиться об этой очереди? Обычно вы этого не сделаете. Но если у вас есть сложная анимационная последовательность, которой вы хотите управлять, то методы очереди / очереди - ваш друг.

Также посмотрите этот интересный разговор в группе jQuery о создании сложной анимационной последовательности.

http://groups.google.com/group/jquery-en/browse_thread/thread/b398ad505a9b0512/f4f3e841eab5f5a2?lnk=gst

Демо анимации:

http://www.exfer.net/test/jquery/tabslide/

Дайте мне знать, если у вас все еще есть вопросы.

488
The uses of jQuery .queue() and .dequeue()

Очереди в jQuery используются для анимации. Вы можете использовать их для любых целей. Ониarray of functions хранится на основе каждого элемента, используяjQuery.data(), Они первыми-первыми-первыми (FIFO). Вы можете добавить функцию в очередь, вызвав.queue()и вы удаляете (вызывая) функции, используя.dequeue().

Чтобы понять внутренние функции очереди jQuery,читая источник и просмотр примеров очень помогает мне. Один из лучших примеров функции очереди, которую я видел, -.delay():

$.fn.delay = function( time, type ) {
  time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
  type = type || "fx";

  return this.queue( type, function() {
    var elem = this;
    setTimeout(function() {
      jQuery.dequeue( elem, type );
    }, time );
  });
};
The default queue - fx

Очередь по умолчанию в jQueryfx, Очередь по умолчанию имеет некоторые специальные свойства, которые не используются совместно с другими очередями.

Auto Start: When calling $(elem).queue(function(){}); the fx queue will automatically dequeue the next function and run it if the queue hasn't started. 'inprogress' sentinel: Whenever you dequeue() a function from the fx queue, it will unshift() (push into the first location of the array) the string "inprogress" - which flags that the queue is currently being run. It's the default! The fx queue is used by .animate() and all functions that call it by default.

NOTE: Если вы используете пользовательскую очередь, вы должны вручную.dequeue() функции, они не будут автоматически запускаться!

Retrieving/Setting the queue

Вы можете получить ссылку на очередь jQuery, вызвав.queue() без аргумента функции. Вы можете использовать метод, если вы хотите увидеть, сколько элементов в очереди. Ты можешь использоватьpush, pop, unshift, shift манипулировать очередью на месте. Вы можете заменить всю очередь, передав массив в.queue() функция.

Quick Examples:

// lets assume $elem is a jQuery object that points to some element we are animating.
var queue = $elem.queue();
// remove the last function from the animation queue.
var lastFunc = queue.pop(); 
// insert it at the beginning:    
queue.unshift(lastFunc);
// replace queue with the first three items in the queue
$elem.queue(queue.slice(0,3)); 
An animation (fx) queue example:

Пример запуска на jsFiddle

$(function() {
    // lets do something with google maps:
    var $map = $("#map_canvas");
    var myLatlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {zoom: 8, center: myLatlng, mapTypeId: google.maps.MapTypeId.ROADMAP};
    var geocoder = new google.maps.Geocoder();
    var map = new google.maps.Map($map[0], myOptions);
    var resized = function() {
        // simple animation callback - let maps know we resized
        google.maps.event.trigger(map, 'resize');
    };

    // wait 2 seconds
    $map.delay(2000);
    // resize the div:
    $map.animate({
        width: 250,
        height: 250,
        marginLeft: 250,
        marginTop:250
    }, resized);
    // geocode something
    $map.queue(function(next) {
        // find stackoverflow's whois address:
      geocoder.geocode({'address': '55 Broadway New York NY 10006'},handleResponse);

      function handleResponse(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
              var location = results[0].geometry.location;
              map.setZoom(13);
              map.setCenter(location);
              new google.maps.Marker({ map: map, position: location });
          }
          // geocoder result returned, continue with animations:
          next();
      }
    });
    // after we find stack overflow, wait 3 more seconds
    $map.delay(3000);
    // and resize the map again
    $map.animate({
        width: 500,
        height: 500,
        marginLeft:0,
        marginTop: 0
    }, resized);
});
Another custom queue example

Пример запуска на jsFiddle

var theQueue = $({}); // jQuery on an empty object - a perfect queue holder

$.each([1,2,3],function(i, num) {
  // lets add some really simple functions to a queue:
  theQueue.queue('alerts', function(next) { 
    // show something, and if they hit "yes", run the next function.
    if (confirm('index:'+i+' = '+num+'\nRun the next function?')) {
      next();
    }
  }); 
});

// create a button to run the queue:
$("<button>", {
  text: 'Run Queue', 
  click: function() { 
    theQueue.dequeue('alerts'); 
  }
}).appendTo('body');

// create a button to show the length:
$("<button>", {
  text: 'Show Length', 
  click: function() { 
    alert(theQueue.queue('alerts').length); 
  }
}).appendTo('body');
Queueing Ajax Calls:

Я разработал$.ajaxQueue() плагин, который использует$.Deferred, .queue(), а также$.ajax() также передать обратнообещание это решается, когда запрос завершается. Другая версия$.ajaxQueue то, что все еще работает в 1.4, опубликовано в моем ответеСеквенирование Ajax-запросов

/*
* jQuery.ajaxQueue - A queue for ajax requests
* 
* (c) 2011 Corey Frang
* Dual licensed under the MIT and GPL licenses.
*
* Requires jQuery 1.5+
*/ 
(function($) {

// jQuery on an empty object, we are going to use this as our Queue
var ajaxQueue = $({});

$.ajaxQueue = function( ajaxOpts ) {
    var jqXHR,
        dfd = $.Deferred(),
        promise = dfd.promise();

    // queue our ajax request
    ajaxQueue.queue( doRequest );

    // add the abort method
    promise.abort = function( statusText ) {

        // proxy abort to the jqXHR if it is active
        if ( jqXHR ) {
            return jqXHR.abort( statusText );
        }

        // if there wasn't already a jqXHR we need to remove from queue
        var queue = ajaxQueue.queue(),
            index = $.inArray( doRequest, queue );

        if ( index > -1 ) {
            queue.splice( index, 1 );
        }

        // and then reject the deferred
        dfd.rejectWith( ajaxOpts.context || ajaxOpts,
            [ promise, statusText, "" ] );

        return promise;
    };

    // run the actual query
    function doRequest( next ) {
        jqXHR = $.ajax( ajaxOpts )
            .done( dfd.resolve )
            .fail( dfd.reject )
            .then( next, next );
    }

    return promise;
};

})(jQuery);

I have now added this as an article on learn.jquery.comНа этом сайте есть и другие замечательные статьи об очередях.

Чтобы добавить одну вещь для тех, кто только изучает очереди и обещания и т. Д. - в примере ajaxQueue вызов $ .ajaxQueue (), в который вы помещаете запрос ajax, который вы хотите поместить в очередь внутри (), возвращает обещание. Вы ожидаете, пока очередь не опустеет, - через обещание. Function () {alert (& quot; done & quot;)}) ;. Мне понадобился час, чтобы найти это, так что надеюсь, что это поможет кому-то еще спасти свой час!
@idealmachine - Как видно из примера очереди Ajax, вы можете прикрепить события очереди к пустому объекту:$({})
+1. Я работаю над пользовательским сценарием на основе jQuery, который должен подключаться к сценарию PHP, как если бы это был другой сценарий PHP, выполняющийся на клиенте, - один HTTP-запрос / другая операция за раз, так что это определенно будет полезно. Просто вопрос: jQuery требует, чтобы очереди были прикреплены к объектам, верно? Так какой объект я должен использовать?$(window)?
Это резюме невероятно полезно. Я только что закончил сборку ленивого загрузчика для задержки запроса на тяжелый контент, который находится ниже нижней части экрана, пока он не прокрутится. Использование jQuery's queue () сделало эти запросы Ajax очень плавными (даже если вы прыгаете прямо в конец страницы). Спасибо!
Приятно узнать, что вы все еще обновляете это для более новых версий jQuery. +1 :)
8

но я использовал $ .queue по-другому и подумал, что я опубликую то, что придумал, здесь. Что мне было нужно, так это последовательность событий (фреймов), которая должна быть запущена, но последовательность, которая должна быть построена динамически. У меня есть переменное количество заполнителей, каждый из которых должен содержать анимированную последовательность изображений. Данные хранятся в массиве массивов, поэтому я циклически перебираю массивы, чтобы построить каждую последовательность для каждого из заполнителей следующим образом:

/* create an empty queue */
var theQueue = $({});
/* loop through the data array */
for (var i = 0; i < ph.length; i++) {
    for (var l = 0; l < ph[i].length; l++) {
        /* create a function which swaps an image, and calls the next function in the queue */
        theQueue.queue("anim", new Function("cb", "$('ph_"+i+"' img').attr('src', '/images/"+i+"/"+l+".png');cb();"));
        /* set the animation speed */
        theQueue.delay(200,'anim');
    }
}
/* start the animation */
theQueue.dequeue('anim');

Это упрощенная версия скрипта, к которому я пришел, но он должен показать принцип - когда функция добавляется в очередь, она добавляется с помощью конструктора Function - таким образом, функция может быть написана динамически с использованием переменных из цикла ( с). Обратите внимание на способ, которым функции передается аргумент для вызова next (), и это вызывается в конце. Функция в этом случае не имеет временной зависимости (она не использует $ .fadeIn или что-то в этом роде), поэтому я разбиваю кадры с помощью $ .delay.

$ .queue - это, по сути, толчок к массиву, хранящемуся в $ .data, поэтому вы должны вручную указать ему выполнить следующую функцию с помощью cb (); Правильно ли мое понимание?
Можете ли вы предоставить ссылку на рабочий пример этого? Возможно в jsfiddle.net ...
-1

makeRed а такжеmakeBlack использованиеqueue а такжеdequeue казнить друг друга. Эффект заключается в том, что «вау» элемент постоянно мигает.

<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
          $('#wow').click(function(){
            $(this).delay(200).queue(makeRed);
            });
          });

      function makeRed(){
        $('#wow').css('color', 'red');
        $('#wow').delay(200).queue(makeBlack);
        $('#wow').dequeue();
      }

      function makeBlack(){
        $('#wow').css('color', 'black');
        $('#wow').delay(200).queue(makeRed);
        $('#wow').dequeue();
      }
    </script>
  </head>
  <body>
    <div id="wow"><p>wow</p></div>
  </body>
</html>

Похожие вопросы