Reputation: 788
The problem I am having is in the run function within the tem.jqw.Callback object. When the run function is called the first time, if the element exists, everything is fine and the executable function runs OK. However, if the element does not yet exist, and we need to loop, the function loses scope after setTimeout(this.run, 100) executes once. For example, when the run function is executing the second time, this.selector or this.fn become undefined. How can I work around this without using global variables? Thanks in advance.
if (typeof tem !== "object") {
tem = {};
}
tem.jqw = {};
tem.jqw.retries = 0;
tem.jqw.maxRetries = 100;
tem.jqw.delay = 100;
tem.jqw.callbacks = [];
tem.jqw.Callback = function (fn, selector, delay) {
this.fn = fn;
this.selector = (typeof selector === "string" && selector.length > 0) ? selector : document;
this.delay = (typeof delay === "number" && delay > 0 && delay < 1000) ? delay : 100;
this.retries = 0;
this.maxRetries = 100;
this.start = function () {
this.run();
};
this.run = function () {
if (jQuery(this.selector).length > 0) {
console.log("[OPDEBUG] tem.jqw.Callback.run says: " + this.selector.toString() + " is ready. Executing callback function...");
this.fn();
} else {
this.retries++;
console.log("[OPDEBUG] tem.jqw.Callback.run says: typeof this.selector " + typeof this.selector);
console.log("[OPDEBUG] tem.jqw.Callback.run says: Waiting for " + this.selector.toString() + "...");
if (this.retries < this.maxRetries) {
setTimeout(this.run, 100);
}
}
};
};
tem.jqw.wait = function () {
if (typeof jQuery === "function") {
console.log("[OPDEBUG] tem.jqw.wait says: jQuery is ready.");
for (var i = 0; i < tem.jqw.callbacks.length; i++) {
if (typeof tem.jqw.callbacks[i] === "object" && typeof tem.jqw.callbacks[i].start === "function") {
console.log("[OPDEBUG] tem.jqw.wait says: Executing callback function " + (i + 1) + "...");
tem.jqw.callbacks[i].start();
}
}
} else {
tem.jqw.retries++;
console.log("[OPDEBUG] tem.jqw.wait says: " + "Waiting for jQuery " + tem.jqw.retries + "...");
if (tem.jqw.retries < tem.jqw.maxRetries) {
setTimeout(tem.jqw.wait, tem.jqw.delay);
}
}
};
tem.jqw.callbacks.push(new tem.jqw.Callback(function () {
jQuery('.hero-inner:first a').css('background-image', 'url("https://www.thedogs.co.nz/Files/PhotoFinishImages/11298_89160.jpg")')
}, ".hero-inner:first"));
tem.jqw.callbacks.push(new tem.jqw.Callback(function () {
jQuery('.RR-placeholder ul li:first').hide();
}, ".RR-placeholder ul li:first"));
tem.jqw.wait();
Upvotes: 1
Views: 552
Reputation: 2943
you can use bind to set this
change this.run()
to
this.run.bind(this)
Its better to assign this to another variable eg)
var self = this;
and then pass around self for better readability
Upvotes: 1