Подтвердить что ты не робот

Как предотвратить jQuery-код от слишком много функций вложенности?

Я не знаю, правильно ли вызывается это гнездование или нет? Но я знаю, что это не хороший код, чтобы иметь много функций внутри друг друга. Большинство методов jQuery имеют функцию обратного вызова, в которой мы можем поместить наши обратные вызовы. Но когда мы выполняем обратные вызовы внутри другого обратного вызова и продолжаем это и все глубже и глубже, кажется, что код становится менее читаемым и, возможно, менее отлаживаемым.

Например, если я хочу сделать несколько анимаций друг за другом, я должен вызывать каждую анимацию, которую я хочу получить после другой, в этой функции обратного вызова. Это будет глубже и глубже в функции обратного вызова. Посмотрите на этот пример (fiddle):

$('#t').animate({height: 400}, 500, function(){
    $(this).animate({height: 200}, 500, function(){
        $(this).animate({width: 300}, 500, function(){
            $(this).animate({height: 300}, 500, function(){
                $(this).animate({'border-radius': '50px'}, 500, function(){
                    //and so on...
                });
            });
        });
    });
});

для выполнения 5-ступенчатой ​​анимации мне нужно сделать 5-уровневый стек вызовов. Итак, мой вопрос в том, как вы избегаете этого? У меня была такая же проблема и в моих Node.js-функциях.

Update: Я знаю, что функция jQuery имеет функцию chinning, но это не решает проблему. потому что вы не можете сделать что-то среднее между цепочкой. Вы можете написать выше код типа $(selector').animate().animate()..., но вы не можете сделать то же самое для этого:

$('#t').animate({height: 400}, 500, function(){
        console.log('step 1 done: like a boss');
        $(this).animate({height: 200}, 500, function(){
            console.log('step 2 done: like a boss');
            $(this).animate({width: 300}, 500, function(){
                console.log('step 3 done: like a boss');
                $(this).animate({height: 300}, 500, function(){
                    console.log('step 4 done: like a boss');
                    $(this).animate({'border-radius': '50px'}, 500, function(){
                        //and so on...
                    });
                });
            });
        });
    });

Идеальным решением будет такой код:

$(selector).doQ(anim1, anim2, myfunc1, anim3, myfunc2)...

Но, к сожалению, у jQuery нет такого API (насколько мне известно).

4b9b3361

Ответ 1

* "Идеальным решением будет такой код:

$(селектор).doQ(anim1, anim2, myfunc1, anim3, myfunc2)..." *

Это не совсем то, что вы хотите, но у jQuery есть queue() [docs] метод:

$(selector).animate({height: 400}, 500)
           .animate({height: 200}, 500)
           .queue( myfunc1 )
           .animate({width: 300}, 500)
           .queue( myfunc2 );

Вам просто нужно убедиться, что ваши функции освободят очередь, когда они будут выполнены, используя dequeue() [docs]:

function myfunc1() {
    // your code
    $(this).dequeue();
}

Или вы можете обернуть свои функции в анонимную функцию и вызвать там dequeue:

$(selector).animate({height: 400}, 500)
           .animate({height: 200}, 500)
           .queue( function( nxt ) {
               myfunc1();
               $(this).dequeue();
            })
           .animate({width: 300}, 500)
           .queue( function( nxt ) {
               myfunc2();
               nxt(); // alternate way to dequeue
            });

Ответ 2

Прочитайте очереди jQuery. Ваш код также может быть написан следующим образом:

$('#t')
    .animate({height: 400}, 500)
    .animate({height: 200}, 500)
    .animate({width: 300}, 500)
    .animate({height: 300}, 500)
    .animate({'border-radius': '50px'}, 500);

Первая анимация запускается немедленно, а остальные помещаются в очередь "fx" и исполняются по очереди, когда остальные заканчиваются.

Ответ 3

Чтение на JQuery Отложенный объект

Это цельный объект утилиты, который может регистрировать несколько обратных вызовов в очереди обратного вызова, вызывать очереди обратного вызова и ретранслировать успех или состояние отказа любой синхронной или асинхронной функции.

Если ваши обратные вызовы являются ТОЛЬКО анимацией, тогда просто соедините их и используйте JQuery fx queue.

Ответ 4

Объекты jQuery имеют очередь по умолчанию. Попробуйте эту скрипту: http://jsfiddle.net/TbkjK/1/

Ответ 5

Немного более чистый способ:

$('#t')
    .animate({height: 400}, 500, animationDone)
    .animate({height: 200}, 500, animationDone)
    .animate({width : 200}, 500, animationDone)
    .animate({height: 300}, 500, animationDone)
    .animate({'border-radius': '50px'}, 500, animationDone);


var logCount = 0;
function animationDone(e) {
    logCount++;

    $("#t").html("Animation # " + logCount + " has completed!");
}

Просто сделайте что-нибудь, основанное на числе logCount. Пример можно увидеть здесь.

Ответ 6

что вы можете сделать, это определить функции с именем и ссылаться на них внутри другой функции, например

  var clicka = function(){
    alert("I got clicked after t.")
  }
  var clickt = function(){
        alert("I got clicked!")
        $('#a').click(clicka)
  }
  $('#t').click(clickt);