Moussawi7
Moussawi7

Reputation: 13267

Use "this" to call a function

When I try to use "this" to call a function, an error occured saying :"this.slideshow_action is not a function". Can you please let me know my fault!?

var class_slider = {
        current_slide: 0, //Starting Slide
        total_slides: 4, //All Slides
        slideshow_action: function(slide_number) {
            $(".slide_text").hide();
            $(".main_navigation_container").removeClass("selected");
            $("#slide_" + slide_number).addClass("selected");
            $("#slide_" + slide_number + "_text").fadeIn("slow");
        },
        slideshow: function() {
            if (this.current_slide === this.total_slides)
                this.current_slide = 0;//Make a new tour
            else
                this.current_slide++;
           this.slideshow_action(this.current_slide);
        },
        reset_timer: function()
        {
            window.clearInterval(this.slideshow_timer);
            this.slideshow_timer = window.setInterval(this.slideshow, 5000);
        },
        icon_action: function(element) {
            this.reset_timer();
            var arr = element.attr("id").split('_'); //Get Last Part of id(slide number)
            this.current_slide = parseInt(arr[1]); //Get slide Number
            this.slideshow_action(this.current_slide);
        }
    };

Upvotes: 2

Views: 109

Answers (5)

Jeffrey W.
Jeffrey W.

Reputation: 4169

The reason why you're seeing this is because the this in your context is not the this you're expecting. Let me explain why.

In JavaScript there's something called the executing context (or that's how I like to refer to it). When a function is called, it's called within a context. Like, for example, when you have an instance of a object the object is the context:

var MyObject = function(){};
MyObject.prototype.myFunction = function() {};
var myObject = new MyObject();
myObject.myFunction();

When you call the myFunction method the context for that method is myObject. If you'd pass this method to the setTimeout method it has no clue as to which object myFunction belongs. Internally it calls it like this theAssignedVariable.call(this);. this in that context is something totally different (window in most cases). So what you're basically seeing is slideshow_action being called on window (this).

To get around issues like this would be do something like:

var _this = this;
setTimeout(function() { 
  _this.callSomeFunction();
}, 1000);

In javascript there's also a bind method on Function. On the MDN they explain how you use this.

The other answers to your question are valid, but none of them explain why it doesn't work.

Upvotes: 1

udidu
udidu

Reputation: 8588

Try changing the setInterval call like so:

this.slideshow_timer = window.setInterval(this.slideshow.bind(this), 5000);

Upvotes: 2

Aleksandr Denisenko
Aleksandr Denisenko

Reputation: 81

Use contexts.

setTimeout(function(context){
        context._someMethod();
    }, 5000, this);
}

var timer = setInterval(function(context){
        context._someMethod();
    }, 5000, this);
}

Upvotes: 3

sanchez
sanchez

Reputation: 4530

function class_slider(){

  var that = {
    current_slide: 0, //Starting Slide
    total_slides: 4, //All Slides
    slideshow_action: function(slide_number) {
        $(".slide_text").hide();
        $(".main_navigation_container").removeClass("selected");
        $("#slide_" + slide_number).addClass("selected");
        $("#slide_" + slide_number + "_text").fadeIn("slow");
    },
    slideshow: function() {
        if (that.current_slide === that.total_slides)
            that.current_slide = 0;//Make a new tour
        else
            that.current_slide++;
       that.slideshow_action(that.current_slide);
    },
    reset_timer: function()
    {
        window.clearInterval(that.slideshow_timer);
        that.slideshow_timer = window.setInterval(that.slideshow, 5000);
    },
    icon_action: function(element) {
        that.reset_timer();
        var arr = element.attr("id").split('_'); //Get Last Part of id(slide number)
        that.current_slide = parseInt(arr[1]); //Get slide Number
        that.slideshow_action(that.current_slide);
    }
  };

  return that;
};

Upvotes: 2

Vitalii Petrychuk
Vitalii Petrychuk

Reputation: 14225

You run this.slideshow from setInterval that is why context is wrong. You can bind function to the context, use jQuery proxy, use that = this etc.

Upvotes: 1

Related Questions