2013-09-05 2 views
2

У меня есть функция в моем коде, которая анимирует несколько элементов. То, что я хочу сделать, это выполнить последовательность кода, но только после эта функция завершена.Выполнение кода, когда функция завершена

Скажем, например, у меня был:

executeMyAnimationFunction(); 

// Execute this code AFTER executeMyAnimationFunction() has completed 
alert('test'); 

До сих пор я попытался с помощью SetTimeout, но это, кажется, не очень надежны. Я также попытался с помощью .promise(), но это, кажется, не выполняют должным образом либо:

$(executeMyAnimationFunction()).promise().done(function() { 
    alert('test'); 
}); 

Однако я признаю, что использовать его неправильно. В the demo на сайте jquery кажется, что для элементов, которые анимируются, используется функция prom(). Я пытался делать это так:

$('#myAnimatedElement').promise().done(function() { 
    alert('test'); 
}); 

и казалось работать в определенных ситуациях, но в других это не сработало. Интересно, является ли это надежным способом использования prom()?

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

Есть ли простой способ сделать это с помощью jquery/javascript, который мне не хватает?

Благодаря

EDIT: Для того, чтобы показать мою проблему в немного более подробно, здесь точный код, я использую:

<script> 
     $(function() { 

      $(window).bind('hashchange', function (e) { 
       if ($(':animated').length) { 
        return false; 
       } 

       var section = $.param.fragment(); 
       var current = $('#content').children(':visible').attr('id'); 

       $('a').removeClass('active');     

       // If this is the first load of the page, then animate in the initial content 
       if (section === '') {      
        if (current === 'reception') { 
         animateContentIn("reception");       
        } 
        else {       
         $('a[href="#' + section + '"]').addClass('active'); 

         // Animate out existing content 
         animateContentOut(current); 

         setTimeout(function() { 
          animateContentIn("reception"); 
         }, 1000); 
        } 
       } 
       else { 
        // Otherwise find the current page content and animate out 
        animateContentOut(current); 

        setTimeout(function() { 
         animateContentIn(section); 
        }, 1000); 
       }    
      }) 

      // Since the event is only triggered when the hash changes, we need to trigger 
      // the event now, to handle the hash the page may have loaded with. 
      $(window).trigger('hashchange'); 
     });  

     function animateContentIn(activePage) { 
      // Now animate in the new content 
      switch (activePage) { 
       case "floorspace": 
        animateFloorspaceElementsIn(); 
        break; 
       case "reception": 
        animateReceptionElementsIn(); 
        break; 
      } 
     } 

     function animateContentOut(currentPage) { 
      // Now animate in the new content 
      switch (currentPage) { 
       case "floorspace":      
        animateFloorspaceElementsOut(); 
        break; 
       case "reception": 
        animateReceptionElementsOut(); 
        break; 
      } 
     } 

     function animateReceptionElementsIn() { 
      $('#reception').show(); 

      $('#reception .title').animate({ 
       bottom: 520 
      }, 400); 

      $('#reception .tile1').animate({ 
       bottom: 504 
      }, 600); 

      $('#reception .tile2').animate({ 
       bottom: 504 
      }, 700); 

      $('#reception .hero').animate({ 
       bottom: 40 
      }, 1000); 

      $('#reception .content1').animate({ 
       bottom: 8 
      }, 400); 

      $('#reception .content2').animate({ 
       bottom: 8 
      }, 500); 
     } 

     function animateReceptionElementsOut() { 
      $('#reception .title').animate({ 
       bottom: -56 
      }, 400); 

      $('#reception .tile1').animate({ 
       bottom: -136 
      }, 600); 

      $('#reception .tile2').animate({ 
       bottom: -152 
      }, 700); 

      $('#reception .hero').animate({ 
       bottom: -464 
      }, 1000, function() { 
       $('#reception').hide(); 
      }); 

      $('#reception .content1').animate({ 
       bottom: -112 
      }, 400); 

      $('#reception .content2').animate({ 
       bottom: -104 
      }, 500); 
     } 

     function animateFloorspaceElementsIn() { 
      $('#floorspace').show(); 

      $('#floorspace .title').animate({ 
       bottom: 520 
      }, 400); 

      $('#floorspace .tile1').animate({ 
       bottom: 504 
      }, 600); 

      $('#floorspace .tile2').animate({ 
       bottom: 504 
      }, 700); 

      $('#floorspace .hero').animate({ 
       bottom: 40 
      }, 1000); 

      $('#floorspace .content1').animate({ 
       bottom: 8 
      }, 400); 

      $('#floorspace .content2').animate({ 
       bottom: 8 
      }, 500); 
     } 

     function animateFloorspaceElementsOut() { 
      $('#floorspace .title').animate({ 
       bottom: -56 
      }, 400); 

      $('#floorspace .tile1').animate({ 
       bottom: -136 
      }, 600); 

      $('#floorspace .tile2').animate({ 
       bottom: -152 
      }, 700); 

      $('#floorspace .hero').animate({ 
       bottom: -464 
      }, 1000, function() { 
       $('#floorspace').hide(); 
      }); 

      $('#floorspace .content1').animate({ 
       bottom: -112 
      }, 400); 

      $('#floorspace .content2').animate({ 
       bottom: -104 
      }, 500); 
     } 
    </script> 
</head> 
<body> 
    <div id="vert-wrapper"> 
     <div id="wrapper"> 
      <aside id="sidebar"> 
       <nav id="navigation"> 
        <ul> 
         <li><a href="#">Building</a></li> 
         <li><a href="#reception">Reception</a></li> 
         <li><a href="#floorspace">Floor Space</a></li> 
         <li><a href="#">Views</a></li> 
         <li><a href="#">Terraces</a></li> 
         <li><a href="#">Profile</a></li> 
        </ul> 
        <ul> 
         <li><a href="#">Specification</a></li> 
         <li><a href="#">Plans</a></li> 
         <li><a href="#">Location</a></li> 
         <li><a href="#">Ten Storeys</a></li> 
         <li><a href="#">Gallery</a></li> 
         <li><a href="#">Contact</a></li> 
        </ul> 
       </nav> 
      </aside> 
      <div id="content"> 
       <article id="reception"> 
        <h1 class="title"> 
         <img src="/images/reception/title.png" alt="Edge" /> 
        </h1> 
        <img src="/images/reception/1.jpg" alt="" class="tile1" /> 
        <img src="/images/reception/2.jpg" alt="" class="tile2" /> 
        <img src="/images/reception/hero.jpg" alt="" class="hero" /> 
        <img src="/images/reception/content1.jpg" alt="" class="content1" /> 
        <img src="/images/reception/content2.jpg" alt="" class="content2" /> 
       </article> 
       <article id="floorspace"> 
        <h1 class="title"> 
         <img src="/images/floorspace/title.png" alt="Space" /> 
        </h1> 
        <img src="/images/floorspace/1.jpg" alt="" class="tile1" /> 
        <img src="/images/floorspace/2.jpg" alt="" class="tile2" /> 
        <img src="/images/floorspace/hero.jpg" alt="" class="hero" /> 
        <img src="/images/floorspace/content1.jpg" alt="" class="content1" /> 
        <img src="/images/floorspace/content2.jpg" alt="" class="content2" /> 
       </article> 
      </div>   
     </div> 
    </div> 
</body> 

Теперь код я выше действительно работает, однако я дон «Я чувствую, что он очень чистый и не кажется, что он выполняется правильно в 100% случаев.

В принципе, у меня есть дилемма. Я хочу, чтобы иметь возможность выполнить animateContentIn() после animateContentOut() закончен. Единственный способ, которым мне удалось это сделать, - отложить функцию animateContentIn() к моменту, когда потребуется самая длинная анимация - в этом случае это 1000 мс.

Нет ли более аккуратный, более эффективный способ написания этого?

+0

доля код внутри 'executeMyAnimationFunction' –

+3

Добавить обратный вызов функции executeMyAnimationFunction. – j08691

+1

Почему бы вам не использовать функцию обратного вызова самой анимации – bipen

ответ

1

Использовать обратный вызов?

function executeMyAnimationFunction(complete){ 
    $('div').animate({ height: '1px' }, 500, complete); 
} 

Зов это следующим образом:

executeMyAnimationFunction(function(){ 
    console.log('animation complete'); 
}); 

Или, если вы настаиваете на использовании обещаний:

executeMyAnimationFunction(){ 
    var dfd = $.deferred(); 

    $('div').animate({ height: '1px' }, 500, function(){ 
     dfd.resolve(); 
    }); 

    return dfd.promise(); 
} 

executeMyAnimationFunction().done(function(){ 
    console.log('animation complete'); 
}); 
2
function someRandomFunction(){ 
    // This will be executed after myFirstFunction 
} 

function myFirstFunction(callbackFunction){ 
    // Do some stuff 
    alert(1); 
    // Do something slow here 

    // Callback when done: 
    callbackFunction(some, input); 
} 
// Usage: 
myFirstFunction(someRandomFunction); // with existing function 
myFirstFunction(function(){ alert(1);}); // anonymous 

Примечание: Вы можете использовать анонимные функции
Small Demo: http://jsfiddle.net/zcp82/2/

Еще одна тема с хорошей информации: Create a custom callback in JavaScript

0

Пожалуйста, обратитесь Old Post

Это, кажется, как дублированный вопрос, если вы звоните несколько функций, он будет вызывать в последовательности только

Смежные вопросы