jquery - обещание / отложенное возвращение пользовательской функции раньше времени, когда для animate () передано несколько элементов. - PullRequest
0 голосов
/ 12 июля 2020

У меня есть полоса прокрутки в блоке div, который содержит меню боковой панели. Я вношу различные изменения в это меню боковой панели, которые влияют на его ширину / высоту, используя jquery animate (). После завершения анимации мне нужно позвонить в App.updatePerfectScrollbar(psSidebar);, чтобы обновить полосу прокрутки с этими новыми значениями ширины / высоты, если таковые имеются. У меня есть несколько разных сценариев ios, это происходит, поэтому я добавил способность обещания к sidebarHideSub(), которая обрабатывает эти изменения.

Использование 1:

Работает отлично. Он ждет, пока оба вызова sidebarHideSub() завершатся, а затем вызывает App.updatePerfectScrollbar, как и должно.

...code above
parent.addClass('open');
//open the submenu
var p1 = sidebarHideSub(sub, false, 1000, 0).promise();
//get all the top links with submenus EXCEPT the one that was clicked
menu = $('#rsideleft').find('a.collapse').not($(this));
//remove the 'open' class on all menus except the one that was clicked
menu.parent().removeClass('open')
//close all the other submenus
var p2 = sidebarHideSub(menu.parent().find('.subMenu'), true, 1000, 0).promise();

//when finished
$.when(p1, p2).then(function() {
    console.log('update');
    App.updatePerfectScrollbar(psSidebar);
});
...code below

Использование 2:

Это тоже отлично работает *. 1018 *

...code above
parent.removeClass('open');
//close the submenu
sidebarHideSub(sub, true, 1000, 0).promise().then(function(){
    console.log('update');
    App.updatePerfectScrollbar(psSidebar);
});
...code below

Использование 3:

Не работает должным образом. Это не дожидается завершения анимации до выполнения обещания. Я сразу вижу «обновление» в моей консоли, когда она запускает анимацию, а не после ее завершения. Единственная разница, которую я вижу между этим и двумя выше, - это анимация, которая выполняется на нескольких элементах. $('#rsideleft .subMenu') может соответствовать нескольким экземплярам на странице, тогда как приведенные выше будут соответствовать только одному. Итак, я предполагаю, что обещание возвращается немедленно, потому что один из согласованных элементов не требовал никакой анимации, в то время как другие требовали? Это действительно единственная причина, по которой я могу придумать, хотя это не то, чего я ожидал бы от нее.

...code above
if( $('body').hasClass('minimized') ) {
    sidebarHideSub($('#rsideleft .subMenu'), true, 1000, 0).promise().then(function(){
        console.log('update');
        App.updatePerfectScrollbar(psSidebar);
    });
}
...code below

функция:

function sidebarHideSub(el, action, speed, delay) {
    var deferred = new $.Deferred();
        
    if(action) {            
        el.delay(delay).animate({
            opacity: 'hide',
            height: 'hide'
        }, speed, function(){
            deferred.resolve(true);
        })
    } else {
        el.delay(delay).animate({
            opacity: 'show',
            height: 'show'
        }, speed, function(){
            deferred.resolve(true);
        })
    }
    return deferred.promise();
}

Есть идеи о том, почему это ведет себя именно так и как это исправить?

1 Ответ

0 голосов
/ 12 июля 2020

Итак, анимация запускается один раз для каждого, когда совпадают несколько элементов. Итак, то, что я думал, происходит ... обещание было возвращено для согласованного элемента немедленно, поскольку оно не требовало никакой анимации, в то время как другие согласованные элементы требовали. Решением было добавить обещание к анимации и вернуть другое обещание, когда весь «набор» завершит анимацию - если это имеет смысл.

function sidebarHideSub(el, action, speed, delay) {

    var deferred = new $.Deferred();
        
    if(action) {                
        el.delay(delay).animate({
            opacity: 'hide',
            height: 'hide'
        }, speed).promise().then(function() {
            deferred.resolve(true);
        })
    } else {
        el.delay(delay).animate({
            opacity: 'show',
            height: 'show'
        }, speed).promise().then(function() {
            deferred.resolve(true);
        })
    }
    return deferred.promise();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...