Apa itu antrian di jQuery?

387

Saya menemukan dokumen jQuery.com di queue()/ dequeue()terlalu sederhana untuk dipahami. Apa sebenarnya antrian di jQuery? Bagaimana saya harus menggunakannya?

jquerynewbie
sumber
3
Contoh yang bagus untuk memecahkan masalah dengan antrian: stackoverflow.com/questions/5230333/…
gnarf

Jawaban:

488

Penggunaan jQuery .queue()dan.dequeue()

Antrian di jQuery digunakan untuk animasi. Anda dapat menggunakannya untuk tujuan apa pun yang Anda suka. Mereka adalah array fungsi yang disimpan pada basis per elemen, menggunakan jQuery.data(). Mereka adalah First-In-First-Out (FIFO). Anda dapat menambahkan fungsi ke antrian dengan memanggil .queue(), dan Anda menghapus (dengan memanggil) fungsi menggunakan .dequeue().

Untuk memahami fungsi antrian jQuery internal, membaca sumber dan melihat contoh sangat membantu saya. Salah satu contoh terbaik dari fungsi antrian yang pernah saya lihat adalah .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 );
  });
};

Antrian default - fx

Antrian default di jQuery adalah fx. Antrian default memiliki beberapa properti khusus yang tidak dibagi dengan antrian lainnya.

  1. Auto Start: Ketika memanggil $(elem).queue(function(){});parafx antrian secara otomatis akan dequeuefungsi berikutnya dan menjalankannya jika antrian belum dimulai.
  2. sentinel 'inprogress': Setiap kali Anda dequeue()fungsi dari fxantrian, itu akan unshift()(mendorong ke lokasi pertama array) string"inprogress" - yang menandai bahwa antrian sedang dijalankan.
  3. Ini default! The fxantrian digunakan oleh .animate()dan semua fungsi yang menyebutnya secara default.

CATATAN: Jika Anda menggunakan antrian khusus, Anda harus secara manual .dequeue()fungsinya, mereka tidak akan mulai secara otomatis!

Mengambil / Mengatur antrian

Anda dapat mengambil referensi ke antrian jQuery dengan menelepon .queue()tanpa argumen fungsi. Anda dapat menggunakan metode ini jika Anda ingin melihat berapa banyak item dalam antrian. Anda dapat menggunakan push, pop, unshift, shiftuntuk memanipulasi antrian di tempat. Anda dapat mengganti seluruh antrian dengan mengirimkan array ke .queue()fungsi.

Contoh Cepat:

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

Contoh fxantrian animasi ( ):

Jalankan contoh di 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);
});

Contoh antrian khusus lainnya

Jalankan contoh di 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');

Panggilan Antrian Ajax:

Saya mengembangkan $.ajaxQueue()plugin yang menggunakan $.Deferred, .queue()dan $.ajax()juga lulus kembali janji yang diselesaikan ketika selesai permintaan. Versi lain dari $.ajaxQueueyang masih berfungsi di 1.4 diposting pada jawaban saya untuk 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);

Saya sekarang telah menambahkan ini sebagai artikel di learn.jquery.com , ada artikel bagus lainnya di situs itu tentang antrian, lihat.

gnarf
sumber
+1. Saya sedang mengerjakan skrip pengguna berbasis jQuery yang perlu terhubung ke skrip PHP seolah-olah skrip PHP lain yang berjalan pada klien - satu permintaan HTTP / operasi lainnya sekaligus, jadi ini pasti akan sangat membantu. Hanya pertanyaan: jQuery mengharuskan antrian dilampirkan ke objek, bukan? Jadi objek mana yang harus saya gunakan? $(window)?
PleaseStand
3
@idealmachine - Seperti yang terlihat pada contoh Antrian Ajax, Anda sebenarnya dapat melampirkan acara antrian ke objek kosong:$({})
gnarf
3
Ringkasan ini sangat berguna. Saya baru saja selesai membuat pemuat malas untuk menunda permintaan untuk konten berat yang ada di bawah layar hingga digulirkan ke tampilan. Menggunakan antrean jQuery () membuat permintaan Ajax itu sangat lancar (bahkan jika Anda melompat langsung ke bagian bawah halaman). Terima kasih!
Jeff Standen
14
Sangat menyenangkan mengetahui Anda masih memperbarui ini untuk versi jQuery yang lebih baru. +1 :)
Shaz
3
Untuk menambahkan satu hal bagi mereka yang baru belajar antrian dan janji-janji dll - dalam contoh ajaxQueue, panggilan ke $ .ajaxQueue () yang Anda beri Anda permintaan ajax yang ingin Anda antri di dalam () akan mengembalikan janji. Cara Anda menunggu hingga antrian kosong adalah melalui janji.done (fungsi () {alert ("selesai")}) ;. Butuh saya beberapa jam untuk menemukan ini, jadi harap ini membantu orang lain menyelamatkan jam mereka!
Ross
42

Untuk memahami metode antrian, Anda harus memahami bagaimana jQuery melakukan animasi. Jika Anda menulis beberapa panggilan metode bernyawa satu demi satu, jQuery membuat antrian 'internal' dan menambahkan pemanggilan metode ini ke dalamnya. Kemudian ia menjalankan panggilan hidup satu per satu.

Pertimbangkan kode berikut.

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

Metode 'antrian' / 'dequeue' memberi Anda kendali atas 'antrian animasi' ini.

Secara default antrian animasi bernama 'fx'. Saya telah membuat halaman contoh di sini yang memiliki berbagai contoh yang akan menggambarkan bagaimana metode antrian dapat digunakan.

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

Kode untuk halaman contoh di atas:

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

Sekarang Anda mungkin bertanya, mengapa saya harus repot-repot dengan antrian ini? Biasanya, kamu tidak akan. Tetapi jika Anda memiliki urutan animasi rumit yang ingin Anda kontrol, maka metode antrian / dequeue adalah teman Anda.

Lihat juga percakapan menarik ini di grup jQuery tentang membuat urutan animasi yang rumit.

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

Demo animasi:

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

Beri tahu saya jika Anda masih memiliki pertanyaan.

SolutionYogi
sumber
20

Beberapa objek animasi dalam antrian

Berikut adalah contoh sederhana dari beberapa objek animasi dalam antrian.

Jquery memungkinkan kita untuk membuat antrian hanya pada satu objek. Tetapi dalam fungsi animasi kita dapat mengakses objek lain. Dalam contoh ini kita membuat antrian di atas objek #q sambil menggerakkan objek # box1 dan # box2.

Pikirkan antrian sebagai array fungsi. Jadi, Anda dapat memanipulasi antrian sebagai array. Anda dapat menggunakan push, pop, unshift, shift untuk memanipulasi antrian. Dalam contoh ini kita menghapus fungsi terakhir dari antrian animasi dan menyisipkannya di awal.

Ketika kita selesai, kita mulai animasi antrian dengan fungsi dequeue ().

Lihat di 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; }  
enf644
sumber
15

Ini memungkinkan Anda untuk membuat animasi antrian ... misalnya, alih-alih ini

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

Yang memudar elemen dan membuat lebar 100 px secara bersamaan . Dengan menggunakan antrian, Anda dapat mengatur animasi. Jadi satu selesai setelah yang lain.

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

Contoh dari http://docs.jquery.com/Effects/queue

alex
sumber
Ini tidak benar. Ketika Anda memiliki beberapa panggilan 'bernyawa', jQuery menempatkan mereka dalam antrian untuk mengeksekusi mereka satu per satu. Dengan menggunakan metode antrian, sekarang Anda dapat mengakses antrian itu dan memanipulasinya, jika perlu.
SolutionYogi
1
@SolutionYogi - Harap edit jawaban saya jika Anda merasa tidak benar - jawabannya CW dan Anda memiliki cukup perwakilan.
Alex
8

Utas ini banyak membantu saya dengan masalah saya, tetapi saya telah menggunakan $ .queue dengan cara yang berbeda dan berpikir saya akan memposting apa yang saya dapatkan di sini. Yang saya butuhkan adalah urutan peristiwa (bingkai) yang akan dipicu, tetapi urutan yang akan dibangun secara dinamis. Saya memiliki sejumlah tempat penampung variabel, yang masing-masing harus berisi urutan gambar animasi. Data disimpan dalam array array, jadi saya loop melalui array untuk membangun setiap urutan untuk masing-masing placeholder seperti ini:

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

Ini adalah versi sederhana dari skrip yang telah saya sampaikan, tetapi harus menunjukkan prinsip - ketika suatu fungsi ditambahkan ke antrian, ia ditambahkan menggunakan Function constructor - dengan cara ini fungsi tersebut dapat ditulis secara dinamis menggunakan variabel dari loop ( s). Perhatikan cara fungsi menyampaikan argumen untuk panggilan () berikutnya, dan ini dipanggil di bagian akhir. Fungsi dalam kasus ini tidak memiliki ketergantungan waktu (tidak menggunakan $ .FadeIn atau semacamnya), jadi saya mengubah frame menggunakan $ .delay.

bjorsq
sumber
$ .queue pada dasarnya adalah dorongan ke array yang disimpan dalam $. data, itulah sebabnya Anda harus secara manual mengatakannya untuk menjalankan fungsi berikutnya dengan cb (); Apakah pemahaman saya benar?
Eighteyes
-1

Berfungsi makeReddan makeBlackmenggunakan queueserta dequeueuntuk saling mengeksekusi. Efeknya adalah, elemen '#wow' berkedip terus menerus.

<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>
ardsrk
sumber