388 Stimmen

Was sind Warteschlangen in jQuery?

Ich habe das jQuery.com-Dokument über queue() / dequeue() ist zu einfach zu verstehen. Was genau sind Warteschlangen in jQuery? Wie sollte ich sie verwenden?

491voto

gnarf Punkte 103284

Die Verwendung von jQuery .queue() y .dequeue()

Warteschlangen in jQuery werden für Animationen verwendet. Sie können sie für jeden beliebigen Zweck verwenden. Sie sind ein Reihe von Funktionen pro Element gespeichert, unter Verwendung von jQuery.data() . Sie sind First-In-First-Out (FIFO). Sie können der Warteschlange eine Funktion hinzufügen, indem Sie .queue() und Sie entfernen (durch Aufruf) die Funktionen mit .dequeue() .

Die internen jQuery-Warteschlangenfunktionen verstehen, Lesen der Quelle und das Anschauen von Beispielen hilft mir ungemein. Eines der besten Beispiele für eine Warteschlangenfunktion, die ich gesehen habe, ist .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 );
  });
};

Die Standard-Warteschlange - fx

Die Standard-Warteschlange in jQuery ist fx . Die Standard-Warteschlange hat einige besondere Eigenschaften, die andere Warteschlangen nicht haben.

  1. Automatischer Start: Bei einem Anruf $(elem).queue(function(){}); die fx Warteschlange wird automatisch dequeue die nächste Funktion und führt sie aus, wenn die Warteschlange noch nicht gestartet ist.
  2. Sentinel 'inprogress': Wann immer Sie dequeue() eine Funktion aus dem fx Warteschlange, wird es unshift() (an die erste Stelle des Arrays schieben) die Zeichenfolge "inprogress" - die anzeigt, dass die Warteschlange gerade ausgeführt wird.
  3. Das ist die Standardeinstellung! Die fx Warteschlange wird verwendet von .animate() und alle Funktionen, die sie standardmäßig aufrufen.

NOTA: Wenn Sie eine benutzerdefinierte Warteschlange verwenden, müssen Sie manuell .dequeue() die Funktionen, werden sie nicht automatisch gestartet!

Abrufen/Einstellen der Warteschlange

Sie können einen Verweis auf eine jQuery-Warteschlange abrufen, indem Sie .queue() ohne ein Funktionsargument. Sie können die Methode verwenden, wenn Sie sehen möchten, wie viele Elemente sich in der Warteschlange befinden. Sie können die Methode push , pop , unshift , shift um die Warteschlange an Ort und Stelle zu bearbeiten. Sie können die gesamte Warteschlange ersetzen, indem Sie ein Array an die Funktion .queue() Funktion.

Schnelle Beispiele:

// 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)); 

Eine Animation ( fx ) Beispiel Warteschlange:

Beispiel auf jsFiddle ausführen

$(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);
});

Ein weiteres Beispiel für eine benutzerdefinierte Warteschlange

Beispiel auf jsFiddle ausführen

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');

Ajax-Aufrufe in die Warteschlange stellen:

Ich habe eine $.ajaxQueue() Plugin, das die $.Deferred , .queue() y $.ajax() um auch eine Versprechen die aufgelöst wird, wenn die Anfrage abgeschlossen ist. Eine andere Version von $.ajaxQueue die in 1.4 noch funktioniert, steht in meiner Antwort auf Sequenzierung von Ajax-Anfragen

/*
* 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);

Ich habe dies nun als Artikel auf learn.jquery.com Auf dieser Website gibt es noch weitere großartige Artikel über Warteschlangen, schauen Sie mal rein.

43voto

SolutionYogi Punkte 30824

Um die Queue-Methode zu verstehen, müssen Sie wissen, wie jQuery Animationen erstellt. Wenn Sie mehrere animate-Methodenaufrufe nacheinander schreiben, erstellt jQuery eine "interne" Warteschlange und fügt diese Methodenaufrufe dazu. Dann werden diese Animationsaufrufe einer nach dem anderen ausgeführt.

Beachten Sie den folgenden Code.

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);
}

Die Methode 'queue'/'dequeue' gibt Ihnen die Kontrolle über diese 'Animationswarteschlange'.

Standardmäßig heißt die Animationswarteschlange 'fx'. Ich habe hier eine Beispielseite mit verschiedenen Beispielen erstellt, die veranschaulichen, wie die Warteschlangenmethode verwendet werden kann.

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

Code für obige Beispielseite:

$(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);
}

Sie fragen sich jetzt vielleicht, warum ich mich mit dieser Warteschlange beschäftigen sollte? Normalerweise werden Sie das nicht tun. Aber wenn Sie eine komplizierte Animationssequenz haben, die Sie kontrollieren wollen, dann sind Warteschlangen-/Dequeue-Methoden Ihr Freund.

Siehe auch diese interessante Unterhaltung in der jQuery-Gruppe über die Erstellung einer komplizierten Animationssequenz.

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

Demo der Animation:

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

Lassen Sie mich wissen, wenn Sie noch Fragen haben.

20voto

enf644 Punkte 574

Animation mehrerer Objekte in einer Warteschlange

Hier ist ein einfaches Beispiel für die Animation mehrerer Objekte in einer Warteschlange.

Jquery erlaubt es uns, eine Warteschlange über nur ein Objekt zu erstellen. Aber innerhalb der Animationsfunktion können wir auf andere Objekte zugreifen. In diesem Beispiel bauen wir unsere Warteschlange über das Objekt #q auf, während wir die Objekte #box1 und #box2 animieren.

Stellen Sie sich die Warteschlange als eine Reihe von Funktionen vor. Sie können die Warteschlange also wie ein Array manipulieren. Sie können push, pop, unshift, shift verwenden, um die Warteschlange zu manipulieren. In diesem Beispiel entfernen wir die letzte Funktion aus der Animationswarteschlange und fügen sie am Anfang ein.

Wenn wir fertig sind, starten wir die Animationswarteschlange mit der Funktion dequeue().

Siehe bei jsFiddle

html:

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

js:

$(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; }

15voto

alex Punkte 457905

Es ermöglicht Ihnen, Animationen in eine Warteschlange zu stellen... zum Beispiel, statt dieser

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

Das Element wird ausgeblendet und erhält eine Breite von 100 Pixeln. zur gleichen Zeit . Mit der Warteschlange können Sie die Animationen zeitlich staffeln. So wird eine nach der anderen beendet.

$("#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();

Beispiel aus http://docs.jquery.com/Effects/queue

8voto

bjorsq Punkte 81

Dieser Thread hat mir bei meinem Problem sehr geholfen, aber ich habe $.queue auf eine andere Art und Weise verwendet und dachte, ich würde hier posten, was ich mir ausgedacht habe. Was ich brauchte, war eine Sequenz von Ereignissen (Frames), die ausgelöst werden sollten, aber die Sequenz sollte dynamisch erstellt werden. Ich habe eine variable Anzahl von Platzhaltern, von denen jeder eine animierte Sequenz von Bildern enthalten sollte. Die Daten werden in einem Array von Arrays gehalten, so dass ich Schleife durch die Arrays, um jede Sequenz für jeden der Platzhalter wie folgt zu bauen:

/* 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');

Dies ist eine vereinfachte Version des Skripts, zu dem ich gekommen bin, aber es sollte das Prinzip zeigen - wenn eine Funktion zur Warteschlange hinzugefügt wird, wird sie mit dem Funktionskonstruktor hinzugefügt - auf diese Weise kann die Funktion dynamisch unter Verwendung von Variablen aus der/den Schleife(n) geschrieben werden. Beachten Sie die Art und Weise, wie der Funktion das Argument für den next()-Aufruf übergeben wird, und wie dieser am Ende aufgerufen wird. Die Funktion hat in diesem Fall keine zeitliche Abhängigkeit (sie verwendet nicht $.fadeIn oder etwas Ähnliches), daher staffle ich die Frames mit $.delay.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X