Reputation: 13267
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
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
Reputation: 8588
Try changing the setInterval call like so:
this.slideshow_timer = window.setInterval(this.slideshow.bind(this), 5000);
Upvotes: 2
Reputation: 81
Use contexts.
setTimeout(function(context){
context._someMethod();
}, 5000, this);
}
var timer = setInterval(function(context){
context._someMethod();
}, 5000, this);
}
Upvotes: 3
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
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