คิวใน jQuery คืออะไร


387

ฉันพบเอกสาร jQuery.com บนqueue()/ dequeue()ง่ายเกินไปที่จะเข้าใจ คิวใน jQuery คืออะไร ฉันจะใช้มันได้อย่างไร


3
ตัวอย่างที่ดีของการแก้ปัญหาคิว: stackoverflow.com/questions/5230333/…
gnarf

คำตอบ:


488

การใช้งานของ jQuery .queue()และ.dequeue()

Queues in 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คือ คิวเริ่มต้นมีคุณสมบัติพิเศษบางอย่างที่ไม่ได้ใช้ร่วมกับคิวอื่น ๆ

  1. เริ่มต้นอัตโนมัติ:เมื่อโทรคิวอัตโนมัติจะฟังก์ชั่นต่อไปและเรียกใช้มันถ้าคิวไม่ได้เริ่ม$(elem).queue(function(){});fxdequeue
  2. 'inprogress' sentinel:เมื่อใดก็ตามที่คุณdequeue()ใช้ฟังก์ชันจากfxคิวมันจะunshift()(ผลักเข้าไปในตำแหน่งแรกของอาร์เรย์) สตริง"inprogress"- ซึ่งแฟล็กที่คิวกำลังทำงานอยู่ในปัจจุบัน
  3. มันเป็นค่าเริ่มต้น! 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ตัวอย่างคิวภาพเคลื่อนไหว ( )

รันตัวอย่างบน 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);
});

ตัวอย่างคิวที่กำหนดเองอื่น

รันตัวอย่างบน 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');

การโทรเข้า Ajax:

ผมพัฒนา$.ajaxQueue()ปลั๊กอินที่ใช้$.Deferred, .queue()และ$.ajax()ยังผ่านการกลับมาสัญญาว่าจะแก้ไขปัญหาได้เมื่อเสร็จสิ้นการร้องขอ รุ่นอื่น$.ajaxQueueที่ยังใช้งานได้ใน 1.4 ถูกโพสต์ในคำตอบของฉันไปยังคำขอลำดับอาแจ็กซ์

/*
* 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มีบทความที่ยอดเยี่ยมอื่น ๆ ในไซต์นั้นเกี่ยวกับคิวไปดู


+1 ฉันกำลังทำงานกับสคริปต์ผู้ใช้ที่ใช้ jQuery ซึ่งจำเป็นต้องเชื่อมต่อกับสคริปต์ PHP ราวกับว่ามันเป็นสคริปต์ PHP ตัวอื่นที่ทำงานบนไคลเอนต์ - การร้องขอ HTTP / การดำเนินการอื่น ๆ ในแต่ละครั้งดังนั้นสิ่งนี้จะเป็นประโยชน์อย่างแน่นอน เพียงคำถาม: jQuery ต้องการให้คิวถูกแนบกับวัตถุใช่ไหม ดังนั้นฉันควรใช้วัตถุใด $(window)?
กรุณามา

3
@idealmachine - ตามที่เห็นในตัวอย่าง Ajax Queue คุณสามารถแนบเหตุการณ์คิวเข้ากับวัตถุว่างเปล่าได้:$({})
gnarf

3
บทสรุปนี้มีประโยชน์อย่างเหลือเชื่อ ฉันเพิ่งสร้างตัวโหลดแบบขี้เกียจเพื่อชะลอการร้องขอเนื้อหาหนักที่อยู่ด้านล่างของหน้าจอจนกว่าจะเลื่อนลงในมุมมอง การใช้คิวของ jQuery () ทำให้อาแจ็กซ์เหล่านั้นร้องขอได้อย่างราบรื่นมาก (แม้ว่าคุณจะกระโดดตรงไปที่ด้านล่างของหน้า) ขอบคุณ!
Jeff Standen

14
ยินดีที่ได้ทราบว่าคุณยังคงอัปเดตสิ่งนี้สำหรับ jQuery เวอร์ชันใหม่ +1 :)
Shaz

3
ในการเพิ่มสิ่งหนึ่งสำหรับผู้ที่เพิ่งเรียนรู้คิวและสัญญาเป็นต้น - ในตัวอย่าง ajaxQueue การเรียกไปที่ $ .ajaxQueue () ที่คุณใส่คำขอ ajax ที่คุณต้องการคิวภายใน () จะส่งคืนสัญญา วิธีที่คุณรอจนกว่าคิวจะว่างเปล่าคือผ่าน contract.done (function () {alert ("done")}); เอาฉันหนึ่งชั่วโมงเพื่อค้นหาสิ่งนี้ดังนั้นหวังว่านี่จะช่วยคนอื่นประหยัดชั่วโมงของพวกเขา!
Ross

42

เพื่อให้เข้าใจถึงวิธีการเข้าคิวคุณต้องเข้าใจว่า jQuery ทำแอนิเมชั่นอย่างไร หากคุณเขียนวิธีการเคลื่อนไหวหลายวิธีจะเรียกใช้วิธีอื่น 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);
}

วิธี 'คิว' / '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);
}

ตอนนี้คุณอาจถามว่าทำไมฉันถึงต้องกังวลกับคิวนี้ ตามปกติคุณจะไม่ แต่ถ้าคุณมีลำดับภาพเคลื่อนไหวที่ซับซ้อนซึ่งคุณต้องการควบคุมดังนั้นวิธีการจัดคิว / dequeue เป็นเพื่อนของคุณ

ดูการสนทนาที่น่าสนใจในกลุ่ม jQuery เกี่ยวกับการสร้างลำดับภาพเคลื่อนไหวที่ซับซ้อน

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

การสาธิตภาพเคลื่อนไหว:

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

แจ้งให้เราทราบหากคุณยังมีคำถาม


20

ภาพเคลื่อนไหววัตถุหลายรายการในคิว

นี่คือตัวอย่างง่ายๆของการเคลื่อนไหวของวัตถุหลายรายการในคิว

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>

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

15

มันช่วยให้คุณจัดลำดับภาพเคลื่อนไหว ... เช่นแทนที่จะเป็นแบบนี้

$('#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


สิ่งนี้ไม่ถูกต้อง เมื่อคุณมีการโทร 'animate' หลายรายการ jQuery จะจัดคิวไว้ในคิวเพื่อเรียกใช้ทีละรายการ ใช้วิธีการคิวตอนนี้คุณสามารถเข้าถึงคิวนั้นและจัดการมันได้ถ้าต้องการ
SolutionYogi

1
@SolutionYogi - โปรดแก้ไขคำตอบของฉันหากคุณคิดว่ามันไม่ถูกต้อง - คำตอบคือ CW'd และคุณมีตัวแทนเพียงพอ
alex

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 Constructor - วิธีนี้สามารถเขียนฟังก์ชันแบบไดนามิกโดยใช้ตัวแปรจากลูป (( s) โปรดสังเกตวิธีที่ฟังก์ชันส่งผ่านอาร์กิวเมนต์สำหรับการเรียก () ครั้งถัดไปและนี่จะถูกเรียกใช้ในตอนท้าย ฟังก์ชั่นในกรณีนี้ไม่มีการพึ่งพาเวลา (มันไม่ได้ใช้ $ .fadeIn หรืออะไรทำนองนั้น) ดังนั้นฉันจึงซวนเซเฟรมโดยใช้ $ .delay


$ .queue นั้นโดยทั่วไปแล้วจะผลักไปยังอาร์เรย์ที่เก็บไว้ใน $ .data ซึ่งเป็นสาเหตุที่คุณต้องบอกให้มันเรียกใช้ฟังก์ชันถัดไปด้วย cb (); ความเข้าใจของฉันถูกต้องหรือไม่
eighteyes

-1

ฟังก์ชั่น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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.