1

I'm trying to do the following:

  1. Fade out a div
  2. Change its text
  3. Fade it in again

The problem is, step 2 is happening before step 1. Why is that happening?

Here's the code:

<p id="p">
     hi!
</p>
<button onclick="foo()">
    wefew
</button>
<script>
    $("button").click(function (){
        var item = $("#p");
        item.hide("slow");
        item.text("text");
        item.show("slow");
    })
</script>

https://jsfiddle.net/pq35yd5t/ edit: I found that the problem is that I'm using a for loop and that the callback function only work on ht elast loop... why, again code:

for (var i = 0; i < ob_prop.length; i++) {
        if (ob_prop[i]=="tag") {
            continue;
        }
        var item = $("#"+ob_prop[i]);
        item.hide("slow", function() {
            item.text(work[pointer][ob_prop[i]]).show("slow");
        });
    }
S. josh
  • 79
  • 7
  • Possible duplicate of [Call a function after previous function is complete](https://stackoverflow.com/questions/5000415/call-a-function-after-previous-function-is-complete) – Tot Zam Sep 25 '17 at 16:04

1 Answers1

4

Because fading is an asynchronous operation.

To do what you're doing, use the callback on hide:

$("button").click(function (){
    var item = $("#p");
    item.hide("slow", function() {
        item.text("text");
        item.show("slow");
    });
})

In a comment you've said:

ok i have tried it but in the original code there's a for loop and function work only at the end of the loop

The callback will have this set to the element related to the callback, so use that rather than item:

$("button").click(function (){
    var item = $("#p");
    item.hide("slow", function() {
        $(this).text("text").show("slow");
    });
})

Your latest edit has the closures in loops problem. See that question's answers for details, but one of the solutions is to use $.each (or Array.prototype.forEach if you don't have to worry about obsolete browsers like IE8):

$.each(function(index, ob) {
    if (ob != "tag") {
        $(ob).hide("slow", function() {
            $(this).text(work[pointer][ob]).show("slow");
        });
    }
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • ok i have tried it but in the original code there's a for loop and function work only at the end of the loop... – S. josh Sep 25 '17 at 16:17
  • @S.josh: Then you'll want to use `this`; I've added to the answer. – T.J. Crowder Sep 25 '17 at 16:20
  • @S.josh: That's the [closures in loops problem](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example), nothing to do with your original code (but that happens sometimes when you do an MCVE, no worries). The answers there should sort out that aspect. I've added *one* of the options to the end of the above. – T.J. Crowder Sep 25 '17 at 17:15