admin管理员组

文章数量:1414878

It simple to understand chaining concept in jQuery but following chaining in jQuery is not giving desired result. Why it makes font-color blue on button click instead of red and then blue (chain-wise)??

<!DOCTYPE html>
<html>
  <head>
   <script src=".12.0/jquery.min.js"></script>
   <script>
      $(document).ready(function(){
        $("button").click(function(){
        // The following code should make the text-color as red   
        //   and then perform the other chaining function,   
        //     but its not making it red, instead it makes it blue on button click. 
           $("#p1").css("color", "red")
                   .slideUp(2000)
                   .slideDown(2000)
                   .css("color", "blue")
                   .slideUp(2000)
                   .slideDown(2000);
        });
     });
   </script>
  </head>
  <body>
    <p id="p1">jQuery is fun!!</p>
    <button>Click me</button>
 </body>
</html>

The above jQuery code should make the text-color as red and then perform the other chaining function, but its not making it red, instead it makes it blue on button click.

It simple to understand chaining concept in jQuery but following chaining in jQuery is not giving desired result. Why it makes font-color blue on button click instead of red and then blue (chain-wise)??

<!DOCTYPE html>
<html>
  <head>
   <script src="https://ajax.googleapis./ajax/libs/jquery/1.12.0/jquery.min.js"></script>
   <script>
      $(document).ready(function(){
        $("button").click(function(){
        // The following code should make the text-color as red   
        //   and then perform the other chaining function,   
        //     but its not making it red, instead it makes it blue on button click. 
           $("#p1").css("color", "red")
                   .slideUp(2000)
                   .slideDown(2000)
                   .css("color", "blue")
                   .slideUp(2000)
                   .slideDown(2000);
        });
     });
   </script>
  </head>
  <body>
    <p id="p1">jQuery is fun!!</p>
    <button>Click me</button>
 </body>
</html>

The above jQuery code should make the text-color as red and then perform the other chaining function, but its not making it red, instead it makes it blue on button click.

Share Improve this question edited Apr 19, 2016 at 15:29 Sohail asked Apr 19, 2016 at 15:22 SohailSohail 5743 silver badges21 bronze badges 4
  • Nest slideXX calls. – Tushar Commented Apr 19, 2016 at 15:22
  • 2 you need to use the call back functions of slide up and down if you are wanting to change the css AFTER the animations have finished - eg slideDown(200, function() { $(this).css("color", "blue") }) – Pete Commented Apr 19, 2016 at 15:27
  • 1 JS ments would be more appropriate here – alex Commented Apr 19, 2016 at 15:28
  • its not chaining its builder pattern. – Pramod S. Nikam Commented Apr 19, 2016 at 15:28
Add a ment  | 

5 Answers 5

Reset to default 5

You need to use the callbacks provided by the animation functions otherwise the effects are executed immediately, instead of after the animation pletes. Try this:

$("button").click(function() {
    $("#p1").css("color", "red").slideUp(2000, function() {
        $(this).css("color", "blue").slideDown(2000, function() {
            $(this).slideUp(2000, function() {
                $(this).slideDown(2000);
            });
        });
    });
});

Working example

If you have a lot of chained animations it may be worthwhile looking in to using queues.

You can use callbacks to execute code after an animation finishes. Otherwise, jQuery will do everything it can right away. Chaining doesn't work like a queue.

$("button").click(function(){
  $("#p1").css("color", "red")
    .slideUp(2000)
    .slideDown(2000, function(){
    	$(this).css("color", "blue");
    })
    .slideUp(2000)
    .slideDown(2000);
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="p1">jQuery is fun!!</p>
<button>Click me</button>

You need to use the available callback functions from the slideUp() and slideDown() functions respectively as the documentation mentions:

If supplied, the callback is fired once the animation is plete. This can be useful for stringing different animations together in sequence. The callback is not sent any arguments, but this is set to the DOM element being animated. If multiple elements are animated, it is important to note that the callback is executed once per matched element, not once for the animation as a whole.

So your the "chaining" approach will look quite a bit different than your original example :

$("#p1").css('color','red')
        .slideUp(2000,function(){
             // When the first slide-up has pleted, then slide down
             $(this).slideDown(2000,function(){
                  // After you have slid-down, change your color
                  $(this).css('color','blue');
                  // Continue down the rabbit hole here...
             });
         });

Working Example

<!DOCTYPE html>
<html>
  <head>
   <script src="https://ajax.googleapis./ajax/libs/jquery/1.12.0/jquery.min.js"></script>
   <script>
      $(document).ready(function(){
        $("button").click(function(){
           $("#p1").css("color", "red")
                   .slideUp(2000, function(){
                      $(this).slideDown(2000,function(){
                        $(this).slideDown(2000).css("color", "blue");
                      })
                   })
          });
     });
   </script>
  </head>
  <body>
    <p id="p1">jQuery is fun!!</p>
    <button>Click me</button>
 </body>
</html>

jQuery chaining executes one function after the other immediately, so the text colour is being set to red, two animations are being queued and then the colour is being set to blue.

Because the slideUp / slideDown functions queue an event rather than wait for it to plete, the text colour changes are happening almost immediately after each other.

You can set an onComplete listener for the slide functions like so:

$("#p1").css("color", "red")
    .slideUp(2000)
    .slideDown(2000)
    .slideUp(2000, function() { $(this).css("color", "blue"); } )
    .slideDown(2000);

Now, your text colour is being set to blue after the second slideUp function finishes, rather than after it's queued.

If you are expecting following flow - change color to red - slide up - slide down - change color to blue - slide up - slide down

then you should use callbacks provided by slideup/slidedown function & nest them properly to get desired effects.

You can do something like

//change color to red
$("#p1").css("color","red");
$("#p1").slideUp(2000,
function(){
    $("#p1").slideDown(2000,
    function(){
        $("#p1").css("color","blue")
        //dotimeoutifyouwanthere
        $("#p1").slideUp(2000,
        function(){
            $("#p1").slideDown(2000);
        })
    })
})

For more details about nesting & callbacks check slideup,slideDown

本文标签: javascriptjQuery chaining not working as expectedStack Overflow