2012-03-07 40 views
11

Làm cách nào để hủy lời hứa mà không xóa phần tử khỏi DOM?Hủy lời hứa hoãn lại trong jQuery

fiddle

tôi chạy mã này:

$("#box") 
    .delay(2000) 
    .show("slow") 
    .delay(2000) 
    .promise()        
    .then(function(){log("Done");}); 

Sau này, có cách nào để hủy bỏ lời hứa? Cả hai clearQueue()stop(true) không hoạt động, bởi vì đó không phải là hoạt ảnh mà tôi đang cố hủy. Tôi thấy rằng remove() nên làm điều đó ... nhưng tôi chỉ muốn dừng lời hứa, không loại bỏ toàn bộ phần tử.

+1

Nếu bạn chỉ có đối tượng lời hứa (và không có quyền truy cập vào trì hoãn ban đầu), thì không thể thực hiện điều đó. Ý tưởng về lời hứa là có thể lắng nghe sự trì hoãn được giải quyết hoặc từ chối, mà không có chức năng giải quyết/từ chối. Những gì bạn có thể làm là tạo ra một wrapper lời hứa cho thấy functons lời hứa ban đầu, nhưng tất cả các callback được liên kết với một hàm bao gói để nghe một số loại cờ để tránh kích hoạt gọi lại nếu hoãn lại bị gắn cờ là bị hủy bỏ. –

+0

gần như, bạn thực sự chỉ muốn tạo ra một từ chối và tự từ chối hoặc giải quyết nó như thế nào bạn thấy phù hợp. –

Trả lời

4

Tin vui. Kể từ hôm qua, bạn có thể hủy lời hứa của mình.

Tôi đã xuất bản phiên bản mới của plugin nhỏ jquery-timing cung cấp hai phương thức trong số nhiều phương thức khác được gọi là .wait() và .unwait().

var deferred = $("#box").delay(2000).show("slow").delay(2000).promise(); 
$.wait(deferred, function(){ log("Done"); }); 

Nếu sau đó bạn muốn hủy đăng ký gọi lại:

$.unwait(); 

Những phiên bản tĩnh của chờ đợi và unwait cũng hỗ trợ một tên nhóm tùy chọn để không hủy bỏ bất kỳ xử lý nhưng chỉ có một tập hợp cụ thể.

Bên cạnh đó bạn có thể làm được rất nhiều thứ thông minh hơn như:

$('#box').wait(deferred).addClass('ready'); 

hoặc toàn bộ mã trong một chuỗi, không lựa chọn unwait:

$("#box").delay(2000).show("slow") 
    .delay(2000).join(function(){log("Done");})).addClass('ready'); 

hoặc cùng thậm chí ngắn hơn với tùy chọn để hủy hai lần tạm dừng:

$("#box").wait(2000).show("slow",$) 
    .wait(2000, function(){log("Done");})).addClass('ready'); 

Chỉ cần xem tài liệu, ví dụ và API phù hợp nhất với bạn.

+0

chỉ là một truy vấn: tôi không thể sử dụng deferred.reject()? –

2

Tôi tin rằng bạn có thể sử dụng $('#box').remove();

Từ các tài liệu jQuery đây: http://api.jquery.com/promise/

Các trở Promise được liên kết với một đối tượng thu nhập hoãn lại được lưu trữ trên .data() cho một phần tử. Vì phương thức .remove() loại bỏ dữ liệu của phần tử cũng như chính phần tử, nó sẽ ngăn cản bất kỳ Lời hứa chưa được giải quyết nào của phần tử khỏi giải quyết. Nếu cần xóa phần tử khỏi DOM trước khi Lời hứa của nó được giải quyết, hãy sử dụng .detach() thay thế và theo sau bằng .removeData() sau khi giải quyết. "

+0

Vâng, tôi thấy 'remove(), nhưng tôi đã tự hỏi nếu có một cách để làm điều đó mà không loại bỏ các yếu tố thực tế. Câu hỏi đã chỉnh sửa. – ripper234

+1

Phải, phải loại bỏ các yếu tố từ mái vòm không có vẻ lý tưởng. Là cách duy nhất tôi có thể làm cho nó hoạt động. Tốt nhất của may mắn trong tìm kiếm của bạn cho một giải pháp tốt hơn. – Paul

1

Tôi không cho rằng bạn muốn một thứ gì đó Giống như http://jsfiddle.net/2cq8M/? Tôi liên quan đến hai lời hứa (một cách để xử lý trường hợp ở cuối tập hợp các hình động, một giải pháp khác để giải quyết hoặc từ chối khi cần.)

+0

Tất nhiên, điều lớn nhất tôi tò mò là những gì được cho là xảy ra với các hình động khi bạn từ chối lời hứa? – JayC

+0

Cú pháp hơi phức tạp ... Tôi đã hy vọng một cách để thực sự hủy lời hứa ... có thể không có cách nào trong việc triển khai hiện tại. – ripper234

1

Bạn muốn sử dụng hoãn trong trường hợp này thay vì một lời hứa, tuy nhiên, bạn có thể sử dụng lời hứa của hoạt ảnh để giải quyết hoãn lại.

http://jsfiddle.net/LG9eZ/9/

var stopDone = true; 

function log(msg) { 
    $(".debug").append(new Date() + " - " + msg + "<br/>"); 
} 

log("Starting"); 

var boxAnimation = new $.Deferred(); 
boxAnimation.done(function() { 
    log("Done"); 
}); 
boxAnimation.fail(function() { 
    log("Stopped"); 
}); 


$("#box").delay(2000).show("slow").delay(2000).promise().then(function() { 
    boxAnimation.resolve(); // when all the animations are done, resolve the deferred. 
}); 


if (stopDone) 
{ 
    boxAnimation.reject(); 
} 

Một lưu ý phụ, trì hoãn chỉ có thể bị từ chối hoặc giải quyết một lần. Khi chúng bị từ chối hoặc giải quyết, bạn không thể thay đổi trạng thái của chúng.

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