Javascript callbacks in object methods

This is more of a question why one of my solutions works and the other doesn't. I am new to JS, only studied for a couple of months and while I have the most foundation, I feel like I am lacking in best practice knowledge.

I am creating an animated hero image for the top of the infographic, and on it, I use JS to create two trains moving across the screen, one from left to right and one from right to left. I created the following code that worked:

    $(document).ready(function() {

        var anim = {
            train1: $(".train-one"),
            train2: $(".train-two"),


            moveLeft: function(percent, duration) {
                 anim.train1.animate({left: percent}, duration, "linear")
            },

            moveRight: function(percent, duration) {
                 anim.train2.animate({right: percent}, duration, "linear")
            },


            leftTrain: function() {
                anim.moveLeft("33%", 1000, anim.moveLeft)
                    anim.moveLeft("66%", 2000, anim.moveLeft)
                         anim.moveLeft("100%", 1000, anim.moveLeft)
                            anim.moveLeft("-100px", 1)
            },

            rightTrain: function() {
                 anim.moveRight("40%", 1000, anim.moveRight)
                    anim.moveRight("60%", 2000, anim.moveRight)
                        anim.moveRight("100%", 1000, anim.moveRight)
                                anim.moveRight("-100px", 1)
            },
        };

        anim.leftTrain();
        anim.rightTrain();
        setInterval(anim.leftTrain, 5000);
        setInterval(anim.rightTrain, 6000);

    });

      

What I'm wondering is why the following didn't work when I expected it, I created a separate method to reset the train when all the callbacks were complete:

        resetLeftTrain: function(test) {
        anim.train1.css("left", "-100px ");
    },

    leftTrain: function() {
        anim.moveLeft("33%", 1000, anim.moveLeft)
            anim.moveLeft("66%", 2000, anim.moveLeft)
                anim.moveLeft("100%", 1000, anim.resetLeftTrain)
                        anim.resetLeftTrain()
    },

      

Sorry if the answer is really obvious, I'm not so used to callbacks in plain JS. Please feel free to give any other pointers regarding structure, etc. Feel it!

Greetings.

EDIT: I solved the problems thanks to the answers below and the code now works fine:

    $(document).ready(function() {

        var anim = {
            train1: $(".train-one"),
            train2: $(".train-two"),


        moveLeft: function(percent, duration, callback) {
            this.train1.animate({left: percent}, duration, "linear", callback)
        },

        moveRight: function(percent, duration, callback) {
            this.train2.animate({right: percent}, duration, "linear", callback)
        },

        resetLeftTrain: function() {
            this.train1.css("left", "-100px");
        },

        resetRightTrain: function() {
            this.train1.css("right", "-100px");
        },

        leftTrain: function() {
            var self = this;

            this.moveLeft("33%", 1000, function() {
                self.moveLeft("66%", 2000, function(){
                    self.moveLeft("100%", 1000, function(){
                        self.resetLeftTrain();
                    });
                });
            });
        },

        rightTrain: function() {
            var self = this;

            this.moveRight("40%", 1000, function() {
                self.moveRight("60%", 2000, function(){
                    self.moveRight("100%", 1000, function(){
                        self.resetRightTrain();;
                    });
                });
            });
        },
    };

    anim.leftTrain();
    anim.rightTrain();
    setInterval($.proxy(anim.leftTrain, anim), 5000);
    setInterval($.proxy(anim.rightTrain, anim), 6000);

    });

      

Next time I can look into the JQuery.promise () method to avoid indenting too ugly.

Thanks for the help, I hope the question and answers will be helpful to others.

+3


source to share


2 answers


You need to provide anonymous callback functions for the animation. Your flaw or half-columns give the impression that they are nested :)

 anim.moveRight("40%", 1000, function(){
    anim.moveRight("60%", 2000, function(){
        anim.moveRight("100%", 1000, function(){
                anim.moveRight("-100px", 1);
        });
     });
 });

      

and make your methods pass the callback:



moveRight: function(percent, duration, callback) {
     anim.train2.animate({right: percent}, duration, "linear", callback);
},

      

The end result is that upon completion of each animation call, it will execute the provided code, effectively combining the animations.

0


source


Year It also took me several weeks to figure out the "callback" - right to right; -)

Here's an example (just for your left train):

$(document).ready(function() {

    var anim = {

        train1: $(".train-one"),

        moveLeft: function(percent, duration, cb) {
            anim.train1.animate({left: percent}, duration, cb);
        },

        leftTrain: function() {
            anim.moveLeft("33%", 1000, function() {
                anim.moveLeft("66%", 2000, function(){
                    anim.moveLeft("100%", 1000, function(){
                        anim.moveLeft("-100px", 1);
                    });
                });
            });

        },
    };

    anim.leftTrain();
    setInterval(anim.leftTrain, 5000);
});

      



Things you should pay attention to:

  • You need to add callbacks (here as a parameter) to your functions.
  • You missed a few ";"
  • If you're having trouble with all the "callback", "lookup", "promises" (jQuery has a built in function for this) or "async.js" <- I really like that
0


source







All Articles