Hàng đợi trong jQuery là gì?


387

Tôi thấy tài liệu jQuery.com trên queue()/ dequeue()quá đơn giản để hiểu. Chính xác thì hàng đợi trong jQuery là gì? Tôi nên sử dụng chúng như thế nào?


3
Một ví dụ điển hình về việc giải quyết vấn đề với hàng đợi: stackoverflow.com/questions/5230333/ trên
gnarf

Câu trả lời:


488

Việc sử dụng jQuery .queue().dequeue()

Hàng đợi trong jQuery được sử dụng cho hình ảnh động. Bạn có thể sử dụng chúng cho bất kỳ mục đích nào bạn thích. Chúng là một mảng các hàm được lưu trữ trên cơ sở từng phần tử, sử dụng jQuery.data(). Họ là người đầu tiên vào trước (FIFO). Bạn có thể thêm một chức năng vào hàng đợi bằng cách gọi .queue()và bạn loại bỏ (bằng cách gọi) các chức năng bằng cách sử dụng .dequeue().

Để hiểu các hàm hàng đợi jQuery bên trong, đọc nguồn và xem các ví dụ giúp tôi rất nhiều. Một trong những ví dụ tốt nhất về chức năng xếp hàng tôi đã thấy là .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 );
  });
};

Hàng đợi mặc định - fx

Hàng đợi mặc định trong jQuery là fx. Hàng đợi mặc định có một số thuộc tính đặc biệt không được chia sẻ với các hàng đợi khác.

  1. Auto Start: Khi gọi $(elem).queue(function(){});các fxhàng đợi sẽ tự động dequeuechức năng tiếp theo và chạy nó nếu hàng đợi vẫn chưa bắt đầu.
  2. Sentinel 'inprowards': Bất cứ khi nào bạn dequeue()có chức năng từ fxhàng đợi, nó sẽ unshift()(đẩy vào vị trí đầu tiên của mảng) chuỗi "inprogress"- cờ mà hàng đợi hiện đang được chạy.
  3. Đó là mặc định! Các fxhàng đợi được sử dụng bởi .animate()và tất cả các chức năng mà gọi nó theo mặc định.

LƯU Ý: Nếu bạn đang sử dụng hàng đợi tùy chỉnh, bạn phải tự thực hiện .dequeue()các chức năng, chúng sẽ không tự động bắt đầu!

Lấy / Đặt hàng đợi

Bạn có thể truy xuất một tham chiếu đến hàng đợi jQuery bằng cách gọi .queue()mà không cần đối số hàm. Bạn có thể sử dụng phương thức nếu bạn muốn xem có bao nhiêu mục trong hàng đợi. Bạn có thể sử dụng push, pop, unshift, shiftđể thao tác các hàng đợi tại chỗ. Bạn có thể thay thế toàn bộ hàng đợi bằng cách chuyển một mảng vào .queue()hàm.

Ví dụ nhanh:

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

Một fxví dụ hàng đợi hoạt hình ( ):

Chạy ví dụ trên 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);
});

Một ví dụ hàng đợi tùy chỉnh khác

Chạy ví dụ trên 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');

Các cuộc gọi Ajax xếp hàng:

Tôi đã phát triển một $.ajaxQueue()plugin mà sử dụng $.Deferred, .queue()$.ajax()cũng để vượt qua trở lại một lời hứa mà đã được giải quyết khi hoàn thành yêu cầu. Một phiên bản khác $.ajaxQueuevẫn hoạt động trong phiên bản 1.4 được đăng trên câu trả lời của tôi cho Trình tự các yêu cầu 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);

Bây giờ tôi đã thêm bài viết này dưới dạng một bài viết trên learn.jquery.com , có những bài viết tuyệt vời khác trên trang web đó về hàng đợi, hãy xem.


+1. Tôi đang làm việc với một tập lệnh người dùng dựa trên jQuery cần kết nối với tập lệnh PHP như thể đó là một tập lệnh PHP khác đang chạy trên máy khách - một yêu cầu HTTP / thao tác khác tại một thời điểm, vì vậy điều này chắc chắn sẽ hữu ích. Chỉ là một câu hỏi: jQuery yêu cầu các hàng đợi được gắn vào các đối tượng, phải không? Vậy tôi nên sử dụng đối tượng nào? $(window)?
Xin vui lòng và

3
@idealmachine - Như đã thấy trong ví dụ Hàng đợi Ajax, bạn thực sự có thể đính kèm các sự kiện xếp hàng vào một đối tượng trống:$({})
gnarf

3
Tóm tắt này là vô cùng hữu ích. Tôi vừa hoàn thành việc xây dựng một trình tải lười biếng để trì hoãn yêu cầu về nội dung nặng nằm dưới đáy màn hình cho đến khi nó được cuộn vào xem. Việc sử dụng hàng đợi của jQuery () đã làm cho các yêu cầu Ajax đó rất trơn tru (ngay cả khi bạn nhảy thẳng xuống cuối trang). Cảm ơn!
Jeff Standen

14
Thật tuyệt khi tìm hiểu bạn vẫn đang cập nhật bản này cho các phiên bản jQuery mới hơn. +1 :)
Shaz

3
Để thêm một điều cho những người chỉ học hàng đợi và lời hứa, v.v. - trong ví dụ ajaxQueue, cuộc gọi đến $ .ajaxQueue () mà bạn đặt cho bạn yêu cầu ajax mà bạn muốn xếp hàng bên trong () sẽ trả lại lời hứa. Cách bạn đợi cho đến khi hàng đợi trống là thông qua lời hứa.done (function () {alert ("xong")});. Đã cho tôi một giờ để tìm thấy điều này, vì vậy hy vọng điều này sẽ giúp người khác tiết kiệm được giờ của họ!
Ross

42

Để hiểu phương thức xếp hàng, bạn phải hiểu cách jQuery hoạt hình. Nếu bạn viết nhiều phương thức animate lần lượt gọi từng phương thức, jQuery sẽ tạo một hàng đợi 'nội bộ' và thêm các cuộc gọi phương thức này vào nó. Sau đó, nó chạy các cuộc gọi animate từng cái một.

Xem xét mã sau đây.

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

Phương pháp 'hàng đợi' / 'dequeue' cho phép bạn kiểm soát 'hàng đợi hoạt hình' này.

Theo mặc định, hàng đợi hoạt hình được đặt tên là 'fx'. Tôi đã tạo một trang mẫu ở đây có các ví dụ khác nhau sẽ minh họa cách sử dụng phương thức xếp hàng.

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

Mã cho trang mẫu trên:

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

Bây giờ bạn có thể hỏi, tại sao tôi phải bận tâm với hàng đợi này? Thông thường, bạn sẽ không. Nhưng nếu bạn có một chuỗi hoạt hình phức tạp mà bạn muốn kiểm soát, thì các phương thức queue / dequeue là bạn của bạn.

Cũng xem cuộc trò chuyện thú vị này trên nhóm jQuery về việc tạo một chuỗi hoạt hình phức tạp.

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

Bản demo của hoạt hình:

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

Hãy cho tôi biết nếu bạn vẫn còn thắc mắc.


20

Nhiều đối tượng hoạt hình trong một hàng đợi

Dưới đây là một ví dụ đơn giản về nhiều đối tượng hoạt hình trong hàng đợi.

Jquery cho phép chúng tôi xếp hàng chỉ trên một đối tượng. Nhưng trong chức năng hoạt hình, chúng ta có thể truy cập các đối tượng khác. Trong ví dụ này, chúng tôi xây dựng hàng đợi của chúng tôi trên đối tượng #q trong khi hoạt hình các đối tượng # box1 và # box2.

Hãy nghĩ về hàng đợi như một mảng các chức năng. Vì vậy, bạn có thể thao tác hàng đợi như một mảng. Bạn có thể sử dụng đẩy, bật, tắt, dịch chuyển để thao tác hàng đợi. Trong ví dụ này, chúng tôi loại bỏ chức năng cuối cùng khỏi hàng đợi hoạt hình và chèn nó vào đầu.

Khi chúng ta hoàn thành, chúng ta bắt đầu xếp hàng hoạt hình bằng hàm dequeue ().

Xem tại 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

Nó cho phép bạn xếp hàng hoạt hình ... ví dụ, thay vì điều này

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

Làm mờ dần phần tử và làm cho chiều rộng 100 px cùng một lúc . Sử dụng hàng đợi cho phép bạn tạo giai đoạn hoạt hình. Vì vậy, một kết thúc sau khi khác.

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

Ví dụ từ http://docs.jquery.com/Effects/queue


Điều này LAF không đúng. Khi bạn có nhiều lệnh gọi 'animate', jQuery sẽ đặt chúng vào hàng đợi để thực hiện từng cái một. Sử dụng phương thức hàng đợi, bây giờ bạn có thể truy cập vào hàng đợi đó và thao tác với nó, nếu cần.
SolutionYogi

1
@SolutionYogi - Vui lòng chỉnh sửa câu trả lời của tôi nếu bạn cảm thấy nó không chính xác - câu trả lời là CW'd và bạn có đủ đại diện.
alex

8

Chủ đề này đã giúp tôi rất nhiều với vấn đề của mình, nhưng tôi đã sử dụng $ .queue theo một cách khác và nghĩ rằng tôi sẽ đăng những gì tôi nghĩ ra ở đây. Những gì tôi cần là một chuỗi các sự kiện (khung) được kích hoạt, nhưng chuỗi được xây dựng linh hoạt. Tôi có một số lượng giữ chỗ khác nhau, mỗi cái nên chứa một chuỗi hình ảnh hoạt hình. Dữ liệu được giữ trong một mảng các mảng, vì vậy tôi lặp qua các mảng để xây dựng từng chuỗi cho từng trình giữ chỗ như thế này:

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

Đây là phiên bản đơn giản của tập lệnh mà tôi đã đến, nhưng sẽ hiển thị nguyên tắc - khi một chức năng được thêm vào hàng đợi, nó được thêm vào bằng cách sử dụng hàm tạo - cách này có thể được viết một cách linh hoạt bằng cách sử dụng các biến từ vòng lặp ( S). Lưu ý cách hàm được truyền đối số cho lệnh gọi () tiếp theo và điều này được gọi ở cuối. Hàm trong trường hợp này không có phụ thuộc thời gian (nó không sử dụng $ .fadeIn hoặc bất cứ thứ gì tương tự), vì vậy tôi sắp xếp lại các khung bằng $ .delay.


$ .queue về cơ bản là một sự thúc đẩy đến một mảng được lưu trữ trong $ .data, đó là lý do tại sao bạn phải tự bảo nó thực hiện hàm tiếp theo với cb (); Tôi hiểu có đúng không?
tám giờ

-1

Chức năng makeRedmakeBlacksử dụng queuedequeueđể thực hiện lẫn nhau. Hiệu quả là, phần tử '#wow' nhấp nháy liên tục.

<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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.