2012-01-09 29 views
86

Kể từ khi tôi đã thêm một số scrollTop -animation, một số bộ phận của callback của tôi được gọi hai lần:Callback của .animate() được gọi hai lần jquery

$('html, body').animate({scrollTop: '0px'}, 300,function() { 
    $('#content').load(window.location.href, postdata, function() {     
     $('#step2').addClass('stepactive').hide().fadeIn(700, function() { 
      $('#content').show('slide',800);      
     }); 
    }); 
}); 

Nó chỉ dường như lặp lại .show(), ít nhất tôi don' t có ấn tượng rằng số load() hoặc số .fadeIn() cũng được gọi lần thứ hai. Các .show() được lặp đi lặp lại ngay sau khi nó đã hoàn thành lần đầu tiên. Đặt tốc độ hoạt ảnh của scrollTop thành 0 không giúp ích gì!

Tôi cho rằng nó có liên quan đến hàng đợi hoạt hình, nhưng tôi không thể tìm ra cách tìm cách giải quyết và đặc biệt là lý do tại sao điều này đang xảy ra.

Trả lời

131

animate gọi callback của nó một lần cho mỗi phần tử trong tập bạn gọi animate trên:

Nếu cung cấp, start, step, progress, complete, done, fail, và always callbacks đang kêu gọi a cơ sở mỗi phần tử ...

Vì bạn đang làm động hai phần tử (phần tử html và phần tử body), bạn sẽ nhận được hai cuộc gọi lại. (Đối với bất cứ ai tự hỏi tại sao OP được hiệu ứng động hai yếu tố, đó là vì các hình ảnh động hoạt động trên body trên một số trình duyệt nhưng trên html trên các trình duyệt khác.)

Để có được một đơn gọi lại khi các hình ảnh động hoàn tất , các animate tài liệu chỉ cho bạn tại bằng cách sử dụng phương pháp promise để có được một lời hứa cho hàng đợi hình ảnh động, sau đó sử dụng then phải xếp hàng gọi lại:

$("html, body").animate(/*...*/) 
    .promise().then(function() { 
     // Animation complete 
    }); 

(Lưu ý: Kevin B chỉ ra điều này in his answer khi câu hỏi được hỏi lần đầu tiên. Tôi đã không cho đến bốn năm sau đó khi tôi nhận thấy nó đã mất tích, thêm nó, và ... sau đó thấy câu trả lời của Kevin. Xin hãy trả lời cho tình yêu của mình xứng đáng. Tôi hình dung như thế này là câu trả lời được chấp nhận, tôi nên rời khỏi nó trong)

Dưới đây là một ví dụ cho thấy cả hai callbacks yếu tố cá nhân, và gọi lại hoàn toàn:.

jQuery(function($) { 
 

 
    $("#one, #two").animate({ 
 
    marginLeft: "30em" 
 
    }, function() { 
 
    // Called per element 
 
    display("Done animating " + this.id); 
 
    }).promise().then(function() { 
 
    // Called when the animation in total is complete 
 
    display("Done with animation"); 
 
    }); 
 

 
    function display(msg) { 
 
    $("<p>").html(msg).appendTo(document.body); 
 
    } 
 
});
<div id="one">I'm one</div> 
 
<div id="two">I'm two</div> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

+2

Vâng đó là lý do và thực sự tôi không thể nhớ tại sao tôi từng viết 'html, body'. Thời gian để biến bộ não của tôi trở lại.Cảm ơn – Anonymous

+20

Có lẽ vì hoạt ảnh chỉ html sẽ không hoạt động trong Webkit và chỉ thân máy sẽ không hoạt động trong Opera. Sử dụng cả hai sẽ đảm bảo nó luôn hoạt động, nhưng sẽ kích hoạt gọi lại hai lần trong Firefox. (Tôi có thể đã nhận được các trình duyệt sai ...) –

+2

'html' là bắt buộc đối với IE và cuộc gọi lại sẽ kích hoạt hai lần đối với hầu hết các trình duyệt khác. Tôi đang cố gắng để làm việc một giải pháp cho cùng một vấn đề. –

159

Để nhận được một cuộc gọi lại đơn để hoàn thành nhiều hoạt ảnh yếu tố, hãy sử dụng các đối tượng hoãn lại.

$(".myClass").animate({ 
    marginLeft: "30em" 
}).promise().done(function(){ 
    alert("Done animating"); 
}); 

Xem API jQuery để biết mô tả chi tiết PromiseDeferred Objects.

+11

Điều này nên được chọn làm câu trả lời đúng .... – Foxhoundn

+0

Điều này được giải quyết vấn đề về những gì chúng tôi muốn thực hiện khi hoàn thành hoạt ảnh nhưng phát hành gấp đôi cuộc gọi và nhận +1 cho điều đó, nhưng tôi không biết liệu quá trình animate được gọi hai lần hay không ?! – QMaster

+1

Quy trình animate không được gọi hai lần, gọi lại được gọi một lần cho mỗi phần tử đã chọn. Vì vậy, nếu bạn chọn 8 mục danh sách và tạo động cho chúng ở bên trái, cuộc gọi lại sẽ được thực hiện 8 lần. Giải pháp của tôi cung cấp cho bạn một cuộc gọi lại duy nhất khi tất cả 8 kết thúc. –

Các vấn đề liên quan