Як заставити jQuery чекати, поки ефект закінчиться?


107

Я впевнений, що читав про це днями, але, здається, ніде його не можу знайти.
У мене є fadeOut()подія, після якої я видаляю елемент, але jQuery видаляє елемент, перш ніж він матиме можливість закінчити згасання.
Як змусити jQuery почекати, поки елемент зів’яне, і видалити його?

Відповіді:


167

Ви можете вказати функцію зворотного дзвінка:

$(selector).fadeOut('slow', function() {
    // will be called when the element finishes fading out
    // if selector matches multiple elements it will be called once for each
});

Документація тут .


Бінго. Я подумав, що це було, але те, що мені потрібно було зробити, це покласти всю свою функцію там, а не лише на частину видалення. PS Якщо когось зацікавила книга, в якій я її прочитав, і я її знову знайшов - це навчання JQuery - краща взаємодія та дизайн. Ще раз
дякую

Якщо хтось має старий jQuery, то ця помилка "зворотний виклик з анімацією" була неприємною: bugs.jquery.com/ticket/5684
JustAMartin

178

З версією jQuery 1.6 ви можете використовувати .promise()метод.

$(selector).fadeOut('slow');
$(selector).promise().done(function(){
    // will be called when all the animations on the queue finish
});

4
Це є надмірним для більшості анімацій jQuery, оскільки у більшості методів є аргументи зворотного виклику, але використовуючи promise()або when()і done()ви можете використовувати дуже класну поведінку від сторонніх методів, або навіть власних. +1 за сенс .promise()!
stuartc

4
Я не чув цього раніше, просто врятував мою недопалку.
prizmspecs

1
у моєму випадку я намагався отримати доступ до поточної анімації елемента, який відбувався десь у моєму коді, і, таким чином, я не мав доступу до його зворотного виклику. +1
Крістіан

11
Використання promis () також дозволяє встановити єдиний зворотний дзвінок, коли все буде зроблено. Якщо ви зателефонуєте fadeOut () на наборі з 10 речей, для кожної речі буде один зворотний виклик, у якому "цей" встановлений у відповідній області. Якщо ви хочете запустити лише один раз, ця функція справді корисна. Також: Якщо ви анімуєте селектор, який виявляється, що відповідає нульовим елементам, звичайний зворотний виклик ніколи не запускається. Обіцянка () вистрілить наприкінці, незважаючи ні на що.
zslayton

6
Ви також можете ланцюг так:$(selector).fadeOut('slow').promise().done(function(){...});
Syclone

9

Ви можете також $.when()дочекатися promiseзавершення:

var myEvent = function() {
    $( selector ).fadeOut( 'fast' );
};
$.when( myEvent() ).done( function() {
    console.log( 'Task finished.' );
} );

У випадку, якщо ви робите запит, який також може бути невдалим, тоді ви можете навіть зробити крок далі:

$.when( myEvent() )
    .done( function( d ) {
        console.log( d, 'Task done.' );
    } )
    .fail( function( err ) {
        console.log( err, 'Task failed.' );
    } )
    // Runs always
    .then( function( data, textStatus, jqXHR ) {
        console.log( jqXHR.status, textStatus, 'Status 200/"OK"?' );
    } );

2
Ця частина цієї відповіді з використанням $.when()не працює, тому myEvent()що не повертає обіцянки і $.when()очікує, що ви виконаєте одну чи кілька обіцянок, щоб вона виконала свою роботу.
jfriend00

6

якщо ви хочете щось переключити, згасаючи одне і згасаючи інше в тому самому місці, ви можете розмістити атрибут {position: absolut} на дівах, тож обидві анімації грають одна над одною, і у вас немає чекати, коли одна анімація закінчиться, перш ніж запустити наступну.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.