Reputation: 13320
I am attempting to collapse a div on request, but my setTimeout function will does not successfully call its callback function. Here is the code below:
function newsFeed() {
this.delete = function(listingID) {
var listing = document.getElementById(listingID);
var currHeight = listing.offsetHeight;
var confirmDelete = confirm("Are you sure you'd like to delete this listing forever?");
if (confirmDelete) {
this.collapse(listingID,currHeight,currHeight,100);
}
}
this.collapse = function(listingID,orig_height,curr_height,opacity) {
var listing = document.getElementById(listingID);
var reduceBy = 10;
if(curr_height > reduceBy) {
curr_height = curr_height-reduceBy;
listing.style.overflow = "hidden";
listing.style.height = (curr_height-40) + "px";
if(opacity > 0) {
opacity = opacity - 10;
var opaque = (opacity / 100);
listing.style.opacity=opaque;
listing.style.MozOpacity=opaque;
listing.style.filter='alpha(opacity='+opacity+')';
}
setTimeout("this.collapse('"+listingID+"',"+orig_height+","+curr_height+","+opacity+")",1);
}
}
}
var newsFeed = new newsFeed();
and I call it in the document as follows:
<div id="closeMe">
<a onclick="newsFeed.delete('closeMe');">close this div</a>
</div>
When it gets to the setTimeout function within this.collapse ... it errors "this.collapse is not a function".
Upvotes: 1
Views: 554
Reputation: 76709
The behavior that you are seeing is because the scoping issue in JavaScript. JavaScript has just two scopes - function and global.
When you perform a setTimeout() call, you have to set variables in the global scope, if you wish to use that state in the code executed due to the setTimeout() call. That would be the fix to the issue; Greg has already suggested a way to do this.
You'll find more information in the Mozilla Developer Center in the pages about setTimeout and in the Core JavaScript Reference.
Upvotes: 1
Reputation: 321598
When the timeout calls you've exited the function and "this" no longer refers to what you think it does.
You should use a closure, like this:
var self = this;
setTimeout(function()
{
self.collapse(listingID, orig_height, curr_height, opacity);
}, 1);
Upvotes: 3
Reputation: 124287
When the timeout is called, this
is no longer what you want it to be. You'll need to refer to the DOM element you want by some other mechanism, perhaps ID-based retrieval.
Upvotes: 0