Baris Demirel
Baris Demirel

Reputation: 150

jquery run functions after another

I have four functions that include jQuery animations and stuff. I want them to run as soon as another finishes. I looked so many SO questions and answers, I have tried so many things (deferred, promise, callback, etc.), but no luck. Usually the result is whether they work simultaneously, or the second doesn't run. Any ideas how can I run them in order?

Here are my functions:

function hides(){
  $('#whiteLogo').hide('600');
  $('div.form').hide('600');
}

function moveTop(){
  $('nav').animate({
    'bottom': 'initial',
    'top': '0px'
  }, 600);
  $('.gradient').animate({
    'bottom': 'initial',
    'top': '-10px'
  }, 600);
}

function destroys(){
  $('.gradient').hide();
}

function content(){
  $('header').after('<section id=\'content\'>\t<div id=\'icons\'>\t</div>\t<section id=\'summary\'>\t\t\t</section>\t<section id=\'bulletin\'>\t\t</section></section>');
}

UPDATE: I don't think it ha something to do with this, but as requested, here is my HTML:

<header>
  <nav>
    <a href='#' class='linkPicture left'>
      <img src='../img/incnetWhite.png' alt='incnetWhite' id='headerLogo'>
    </a>
    <a href='../checkin/index.php' class='linkWord left' id='checkinLink'>
      Checkin
    </a>
    <a href='../weekend/index.php' class='linkWord left' id='weekendLink'>
      Weekend Departures
    </a>
    <a href='../etut/index.php' class='linkWord left' id='etutLink'>
      Etut Reservations
    </a>
    <div class='linkWord left more' id='moreLink'>
      More
      <img src='../img/header-drop.png' alt='drop' class='dropimg'>
      <div class='dropMenu more' id='moreMenu'>
        <a href='../pool/index.php' class='dropWord left' id='poolLink'>
          Pool Reservations
        </a>
        <br>
        <a href='../admin/index.php' class='dropWord left' id='adminLink'>
          Admin Tools
        </a>
      </div>
    </div>
    <div href='#' class='linkWord right personal' id='personalLink'>
      Your Name 
      <img src='../img/header-drop.png' alt='drop' class='dropimg'>
      <div class='dropMenu personal' id='personalMenu'>
        <a href='../core/settings.php' class='dropWord left' id='settingLink'>
          Change Settings
        </a>
        <br>
        <a href='../profiles/edit.php' class='dropWord left' id='profileLink'>
          Profile Settings
        </a>
        <br>
        <a href='../core/hiring.php' class='dropWord left' id='hiringLink'>
          Apply to INÇNET
        </a>
        <br>
        <a href='../core/about.php' class='dropWord left' id='aboutLink'>
          About Us
        </a>
        <br>
        <a href='../core/logoff.php' class='dropWord left' id='logoffLink'>
          Sign Out
        </a>
      </div>
    </div>
  </nav>
</header>   
<div class='form'>
    <form method='POST'>
        <span id='welcome'>Welcome!</span>
        <!--<label class='fieldname' id='username'>Username:</label>-->
        <input type='text' name='username' placeholder='username' size='10'>
        <br>
        <!--<label class='fieldname' id='password'>Password:</label>-->
        <input type='password' name='password' placeholder='&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;&#9679;' size='10'>
        <br>
        <span id='remember'>
            <input type='checkbox' name='remember'>
            <label class='fildname' id='rememberme'>Remember Me</label>
        </span>
        <br>
        <span id='error'>
        </span>
        <input type='submit' name='signin' value='Sign In' id='signin'>
    </form>
</div>

Upvotes: 1

Views: 125

Answers (5)

guest271314
guest271314

Reputation: 1

Edit, updated

Utilizing .queue() , as suggested by Mottie

   function hides(){
      $('#whiteLogo').hide(600);
        $('div.form').hide(600, d);
    };

    function moveTop() {
      $('nav').animate({
        'bottom': 'initial',
        'top': '0px'
      }, 600);
      $('.gradient').animate({
        'bottom': 'initial',
        'top': '-10px'
      }, 600, d);

    };

    function destroys() {
        $('.gradient').hide(600, d);

    };

    function content() {
        $('header').after('<section style=background:blue id=\'content\'>'
        + '\t<div id=\'icons\'>\t</div>\t<section id=\'summary\'>'
        + '\t\t\t</section>\t<section id=\'bulletin\'>'
        + '\t\t</section>section</section>');
    };

$("body").queue("animations", [hides, moveTop, destroys, content]);
var d = function() {
  return $("body").dequeue("animations")
};
hides()

http://jsfiddle.net/guest271314/0Lx4t54y/

Upvotes: 0

Ian Clark
Ian Clark

Reputation: 9357

So far as I can tell, you want to perform events against multiple elements in sequence. With a little bit of playing around we can leverage jQuery's Deferred's and make a solution (view JSFiddle) such as:

function runDeferred() {
    var args = arguments;
    if(args.length) {
        var next = Array.prototype.shift.call(args);
        $.when(next()).done(function() {
            runDeferred.apply(this, args);
        });
    }

This method can takes a list of methods, and calls them consecutively. The methods themselves need to return the a jQuery object of the elements that we wish to wait for. Here's an example of such a method:

function fadeBar() {
    return $("#bar").fadeIn(1000).animate({
        "font-size": "2em"
    }, 1000);
}

And here's how you can combine them:

runDeferred(fadeFoo, fadeBar, fadeZulu);

Upvotes: 1

georgiar
georgiar

Reputation: 379

You didn't share information on how you call the functions. All the animation functions on jQuery has callbacks on complete. To call other function at the moment the animation is complete you can use the following code.

function hides(){
    $('#whiteLogo').hide(600);
    $('div.form').hide(600, moveTop);
}

function moveTop(){
    $('nav').animate({
        'bottom': 'initial',
        'top': '0px'
    }, 600);
    $('.gradient').animate({
        'bottom': 'initial',
        'top': '-10px'
    }, 600, destroys);
}

function destroys(){
    $('.gradient').hide(600, content);
}

function content(){
    $('header').after('<section id=\'content\'>\t<div id=\'icons\'>\t</div>\t<section id=\'summary\'>\t\t\t</section>\t<section id=\'bulletin\'>\t\t</section></section>');
}

This way when you call hide() you'll have a chain of callback one after other. As you can see I only check one of the animations per function because they are limited to the same execution time (Ex. hides() has 2 animations of 600ms, so I assume that if one has finished, the other should have been as well).

Be advised that this piece of code could be refactored in an event driven pattern and if you ask me - think of some kind of better design pattern.

Check jQuery's documentation as well http://api.jquery.com/animate/

Upvotes: 0

Josh Horowitz
Josh Horowitz

Reputation: 665

Callbacks should work. I'm not exactly sure what it is that you're trying to do, but it seems like you're saying you want one to run after another.

function hides(callback){
  $('#whiteLogo').hide('600', function(){
    $('div.form').hide('600', function(){
        if (callback){
            callback();
        }
    });
  });

}

function moveTop(callback){
  $('nav').animate({
    'bottom': 'initial',
    'top': '0px'
  }, 600, function(){
      $('.gradient').animate({
        'bottom': 'initial',
        'top': '-10px'
      }, 600, function(){
          if (callback){
              callback();
          }
      });
  });

}

function destroys(callback){
  $('.gradient').hide(function(){
      if (callback){
          callback();
      }
  });
}


//I have never used after but I'm sure it's similar to the callback structure above.
function content(){
  $('header').after('<section id=\'content\'>\t<div id=\'icons\'>\t</div>\t<section id=\'summary\'>\t\t\t</section>\t<section id=\'bulletin\'>\t\t</section></section>');
}

Callbacks can be used like this.

hides(function(){
   doSomething();
});

Upvotes: 0

DeFeNdog
DeFeNdog

Reputation: 1210

Look into method chaining. That's worked for me in the past.

http://schier.co/post/method-chaining-in-javascript

Upvotes: 0

Related Questions