[jquery] jQuery의 대기열이란 무엇입니까?

나는에 jQuery.com 문서를 발견 queue()/ dequeue()이해하기 너무 간단합니다. jQuery의 대기열은 정확히 무엇입니까? 어떻게 사용해야합니까?



답변

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입니다. 기본 큐에는 다른 큐와 공유되지 않는 일부 특수 특성이 있습니다.

  1. 자동 시작 : 큐를 호출 $(elem).queue(function(){});하면 fx큐가 dequeue시작되지 않은 경우 다음 함수 가 자동으로 실행됩니다.
  2. ‘inprogress’sentinel :dequeue()에서 함수를 수행 할 때마다 큐가 현재 실행되고 있음을 나타내는 문자열이 배열의 첫 번째 위치로 푸시됩니다 .fxunshift()"inprogress"
  3. 기본값입니다! fx큐는 기본적으로 큐 .animate()를 호출하는 모든 함수에서 사용됩니다 .

참고 : 사용자 지정 대기열을 사용하는 경우 수동으로 .dequeue()기능 을 수행해야합니다 . 자동으로 시작되지 않습니다!

대기열 검색 / 설정

.queue()함수 인수없이 호출하여 jQuery 대기열에 대한 참조를 검색 할 수 있습니다 . 대기열에 몇 개의 항목이 있는지 보려면이 방법을 사용할 수 있습니다. 당신이 사용할 수있는 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()또 다시 전달하기 위해 약속을 할 때 요청이 완료 해결됩니다. $.ajaxQueue1.4에서 여전히 작동하는 다른 버전은 시퀀싱 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);

나는 이것을 learn.jquery.com에 기사로 추가 했으며 , 그 사이트에는 대기열에 관한 다른 훌륭한 기사가 있습니다.


답변

대기열 방법을 이해하려면 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);
}

‘queue’/ ‘dequeue’방법을 사용하면이 ‘animation queue’를 제어 할 수 있습니다.

기본적으로 애니메이션 큐의 이름은 ‘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://groups.google.com/group/jquery-en/browse_thread/thread/b398ad505a9b0512/f4f3e841eab5f5a2?lnk=gst

애니메이션 데모 :

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

여전히 궁금한 점이 있으면 알려주세요.


답변

대기열에서 여러 객체 애니메이션

다음은 대기열에서 여러 객체 애니메이션의 간단한 예입니다.

Jquery는 하나의 객체에만 대기열을 만들도록 허용했습니다. 그러나 애니메이션 기능 내에서 다른 객체에 액세스 할 수 있습니다. 이 예에서는 # box1 및 # box2 객체에 애니메이션을 적용하면서 #q 객체 위에 대기열을 만듭니다.

큐를 함수의 배열로 생각하십시오. 따라서 큐를 배열로 조작 할 수 있습니다. 푸시, 팝, 언 시프트, 시프트를 사용하여 큐를 조작 할 수 있습니다. 이 예제에서는 애니메이션 큐에서 마지막 함수를 제거하고 처음에 삽입합니다.

완료되면 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; }  


답변

예를 들어 애니메이션 대신 대기열에 넣을 수 있습니다.

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

어느 요소를 페이드하고 동시에 너비를 100px 만듭니다 . 대기열을 사용하면 애니메이션을 스테이지 할 수 있습니다. 그래서 하나는 다른 후에 끝납니다.

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

이것은 내가 도착한 스크립트의 단순화 된 버전이지만 원리를 보여 주어야합니다-함수가 대기열에 추가되면 함수 생성자를 사용하여 추가됩니다-이 방법으로 함수는 루프의 변수를 사용하여 동적으로 작성할 수 있습니다 에스). 함수에 next () 호출에 대한 인수가 전달되는 방식에 유의하십시오. 이는 마지막에 호출됩니다. 이 경우 함수에는 시간 의존성이 없으므로 ($ .fadeIn 또는 이와 유사한 것을 사용하지 않음) $ .delay를 사용하여 프레임을 비틀 거립니다.


답변

기능 makeRedmakeBlack사용 queuedequeue서로를 실행합니다. 그 결과 ‘#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>


답변