0

I have a .click() event on an element. After it's closed, this mob has a transition that happens and an AJAX call that goes through. That's all that happens.

What I need is a callback to put inside the .click() function to execute when both of those things are done, even if transitions aren't supported. Here's a timeline:

jQuery needs to wait for the ajax call and the transition, then execute the callback after the ajax call has completed AND the transition has either finished or not happened at all.

How can I do this? Thanks!

NOTE: I'm using $.ajax() for the ajax call and a normal CSS3 transition on the element in question. I can detect transitionEnd with javascript event binding, I have a variable setup for that called transitionEnd and another variable that detects if the browser support transitions call supportsTrans.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
alt
  • 13,357
  • 19
  • 80
  • 120
  • *(Ignore that duplicate, I chose the wrong question. I **have** seen at least a couple of variations on this question before, though.)* – T.J. Crowder May 06 '12 at 08:48
  • No, because mine involves the transitionEnd event, making it a bit more complex. – alt May 06 '12 at 08:49
  • @Jackson: Yes, I choose the wrong question and edited the comment. At the end of the day, though, this comes down to: How do I wait until two things have happened? I've definitely seen that question before, and the answer is trivial. – T.J. Crowder May 06 '12 at 08:50
  • I know answer is already done and checked, but how about deferred: http://jsfiddle.net/zerkms/SPqhB/ ? – zerkms May 06 '12 at 09:05
  • possible duplicate of [Two jQuery Event Handlers - execute code when both are fired](http://stackoverflow.com/questions/5909988/two-jquery-event-handlers-execute-code-when-both-are-fired) – Perception May 06 '12 at 11:20
  • 1
    I would use jQuery's Deferred object, which is answered here: http://stackoverflow.com/questions/7432815/jquery-wait-for-multiple-complete-events – thdoan Apr 12 '16 at 12:08

1 Answers1

5

Have a flag for each event, initially false. Hook the two events in question (transitionEnd and the ajax success, it sounds like). Each event sets its flag and calls a function. That function checks the flags: If both are set, it does something.

Here's an example using animate rather than a CSS transition, just to keep things simple: Live example | source

jQuery(function($) {

  $("#theButton").click(function() {
    this.style.display = "none";
    $("#box, #content").show();
    doTheStuff();
  });

  function doTheStuff() {
    var ajaxDone = false,
        ajaxFailed = false,
        animationDone = false;

    display("Triggering ajax and animation");

    $.ajax({
      url: "http://jsbin.com/ibebiv",
      method: "GET",
      success: function(data) {
        $("#content").append(data);
        display("ajax done");
        ajaxDone = true;
        checkDone();
      },
      error: function() {
        ajaxFailed = true;
        checkDone();
      }
    });

    $("#box").animate({
      left: "+200px"
    }, function() {
      display("animation done");
      animationDone  = true;
      checkDone();
    });

    function checkDone() {
      if ((ajaxDone || ajaxFailed) && animationFlag) {
        display("<strong>All done</strong>");
      }
    }
  }

  function display(msg) {
    $("<p>").html(msg).appendTo("#content");
  }
});

Note the error handling, in case the ajax call fails.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • by flag, he meant just a variable I guess. Eg: flag++; inside your call backs of each of your events, and then calling the function itself. if (flag == 2 ) is true, it means both events have taken place. – KBN May 06 '12 at 08:53
  • @JacksonGariety: *"How do I set flags?"* `var flag = false;` and then later `flag = true;` – T.J. Crowder May 06 '12 at 08:57
  • How do I get it to checkDone() to constantly be checking until it goes? Right now it'll just check once when the ajax call finishes. – alt May 06 '12 at 08:59
  • Nevermind, I figured it out. It checks twice. Once at the end of transition and once at the end of ajax. So then the last one will always have the callback! Genius! – alt May 06 '12 at 09:01
  • @JacksonGariety: :-) I've just updated the example so it's all contained in a function, which is more realistic, rather than all being in the `ready` handler (which I suppose is also a function, but...). – T.J. Crowder May 06 '12 at 09:02
  • In `$.ajax()`, `success:Function` is not guaranteed to be invoked. You'll still need to handle Ajax failure case, namely `error:Function` parameter, or, you may put the common logic in `complete:Function`. – Evi Song Feb 06 '16 at 03:05