Я нашел документ jQuery.com на queue()/ dequeue()слишком прост для понимания. Что такое очереди в jQuery? Как я должен их использовать?
Я нашел документ jQuery.com на queue()/ dequeue()слишком прост для понимания. Что такое очереди в jQuery? Как я должен их использовать?
Ответы:
.queue()и.dequeue()Очереди в jQuery используются для анимации. Вы можете использовать их для любых целей. Они представляют собой массив функций, сохраняемых для каждого элемента с использованием 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 );
});
};
fxОчередь по умолчанию в jQuery fx. Очередь по умолчанию имеет некоторые специальные свойства, которые не используются совместно с другими очередями.
$(elem).queue(function(){});в fxочереди будет автоматически dequeueследующая функция и запустить его , если очередь не началась.dequeue()выполняете функцию из fxочереди, она unshift()(помещает в первое место массива) строку "inprogress"- которая указывает, что очередь в данный момент выполняется.fxОчередь используется , .animate()и все функции , которые называют его по умолчанию.ПРИМЕЧАНИЕ. Если вы используете пользовательскую очередь, вы должны вручную включить .dequeue()функции, они не запустятся автоматически!
Вы можете получить ссылку на очередь jQuery, вызвав ее .queue()без аргумента функции. Вы можете использовать метод, если вы хотите увидеть, сколько элементов в очереди. Вы можете использовать push, pop, unshift, shiftуправлять очередью на месте. Вы можете заменить всю очередь, передав массив .queue()функции.
Быстрые примеры:
// 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));
fxочереди анимации ( ):$(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);
});
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');
Я разработал $.ajaxQueue()плагин , который использует $.Deferred, .queue()и $.ajax()также передать обратно обещание , что не будет решена , если запрос не завершится. Другая версия, $.ajaxQueueкоторая все еще работает в 1.4, опубликована в моем ответе на Sequencing Ajax Requests.
/*
* 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);
Теперь я добавил это как статью на learn.jquery.com , на этом сайте есть и другие замечательные статьи об очередях, посмотрите.
$(window)?
$({})
Чтобы понять метод очереди, вы должны понимать, как 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);
}
Метод 'queue' / 'dequeue' дает вам контроль над этой 'очередью анимации'.
По умолчанию очередь анимации называется «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://www.exfer.net/test/jquery/tabslide/
Дайте мне знать, если у вас все еще есть вопросы.
Вот простой пример анимации нескольких объектов в очереди.
Jquery позволяет нам ставить в очередь только один объект. Но внутри функции анимации мы можем получить доступ к другим объектам. В этом примере мы строим нашу очередь поверх объекта #q, анимируя объекты # box1 и # box2.
Думайте об очереди как о массиве функций. Таким образом, вы можете управлять очередью как массивом. Вы можете использовать push, pop, unshift, shift для управления очередью. В этом примере мы удаляем последнюю функцию из очереди анимации и вставляем ее в начале.
Когда мы закончим, мы запускаем очередь анимации с помощью функции dequeue ().
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; }
Это позволяет вам ставить в очередь анимации ... например, вместо этого
$('#my-element').animate( { opacity: 0.2, width: '100px' }, 2000);
Который затемняет элемент и делает ширину 100 пикселей одновременно . Использование очереди позволяет ставить анимацию. Итак, одно заканчивается за другим.
$("#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
Эта ветка очень помогла мне с моей проблемой, но я использовал $ .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.
Функции makeRedи makeBlackиспользовать queueи dequeueвыполнять друг друга. В результате элемент #wow постоянно мигает.
<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>