Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Doesn't work but it should - (setTimeout() related)

Status
Not open for further replies.

Guest_imported

New member
Jan 1, 1970
0
<br>Hi,<br><br>I have been trying to call a function via setTimeout() method but a problem occurs in both major browsers. Before you look in the code, here is a description of what I like to do:<br><br>I want the function &quot;myFunc()&quot; be called every second and each time when myFunc() gets called I like the &quot;this.width&quot; to keep its value. I don't like it to become &quot;undefined&quot;. Now if I do &quot;setTimeout(&quot;myFunc()&quot;, 1000);&quot; &quot;this.width&quot; becomes &quot;undefined&quot; the second time when the myFunc() gets called. So, I thought that to solve the problem I would write setTimeout(&quot;this.method()&quot;, 1000); but it doesn't work.<br><br>Here is the code which I have:<br><br>&lt;html&gt;<br>&lt;head&gt;<br><br>&lt;script language=&quot;JavaS..&quot;&gt; <br><br> // create a class<br> function Test(intW, intH) <br> {<br> this.width = intW;<br> this.height = intH;<br> <br> // assign a method......<br> this.method = myFunc; <br> <br> this.method(); // call the method<br> }<br><br> // define the method for the class<br> function myFunc() <br> {<br> // the first time when this function gets called <br> // from the constructor, this.width in here keeps <br> // the value...like a normal data member in a class..<br> <br> alert(this.width);<br><br> // as you see, this.width was initialated in<br> // the constructor above and then this member function<br> // gets called automatically by the constructor to modify<br> // the current object's data members/fields<br><br><br> // here I modify the current object's &quot;width&quot; property....<br> // which was declared and defined in the constructor above<br><br> this.width = this.width + 10;<br><br> <br><br> // Now, I call this.method() like this because the next time when <br> // this function get called, I want this.width to keep its value<br> // but not become &quot;undefined&quot;<br><br> // Please see the comment below....<br> setTimeout(&quot;this.method()&quot;, 1000); <br> }<br><br><br> <br> // &lt;body onLoad = &quot;hmm()&quot;&gt; ...... <br> function hmm()<br> {<br><br> d = new Test(10, 10);<br> }<br><br><br>&lt;/script&gt;<br><br>&lt;/head&gt;<br><br>&lt;body onLoad=&quot;hmm()&quot;&gt;&lt;/body&gt; &lt;/html&gt;<br><br><br>Now when I run the code, This is the error which I receive in Netscape: <br><br>&quot;this.method is not a function.&quot;.&nbsp;&nbsp;As you can see the problem is in setTimeout() function.<br><br><br>Now if I do: setTimeout(&quot;myFunc()&quot;, 1000); -- that will work but &quot;this.width&quot; will become &quot;undefined&quot; the second time (after one second) when the function gets called and I don't want that. I want &quot;this.width&quot; to keep its value each time the function get called. Sure I can create one global variable but that's not what I like to do. This is what I like to implement without creating a global variable. <br><br>I want the function &quot;myFunc()&quot; be called every second and each time when myFunc() gets called I like the &quot;this.width&quot; to keep its value. I don't like it to become &quot;undefined&quot;. Now as I said if I do &quot;setTimeout(&quot;myFunc()&quot;, 1000);&quot; &quot;this.width&quot; becomes &quot;undefined&quot; the second time when the myFunc() gets called. So, I thought that to solve the problem I would write setTimeout(&quot;this.method()&quot;, 1000); but it doesn't work.<br><br>Could you please suggest me something?<br><br><br>By the way, this problem prevents me from developing my DHTML object/class....<br><br>Thanks,<br><br>Regards:<br>Tonny9 <br><br>&nbsp;<br><br> <br>&nbsp;
 
I think the problem is that the variable (d) is not being saved. you have it as a local variable, within the function hmm. when that function stops executing, which happens in the space after the first setTimeout run of the this.method () function.&nbsp;&nbsp;try adding this somewhere outside of a function, in the javascript:<br><br>var d;<br><br>that should make it work. <p>theEclipse<br><a href=mailto:eclipse_web@hotmail.com>eclipse_web@hotmail.com</a><br><a href=robacarp.webjump.com>robacarp.webjump.com</a><br>**-Trying to build a documentation of a Javascript DOM, crossbrowser, of course. E-mail me if you know of any little known events and/or methods, etc.
 
Tonny9,<br><br>I've had lots of fun(!!??) with setTimeout, especially in conjunction with ojects.<br><br>You don't say what object &quot;this&quot; refers to, so I can answer only in general terms.<br><br>setTimeout has 2 arguments:<br>*&nbsp;&nbsp;a string which is interpreted (effectively by an eval function) on expiry of the timeout.<br>*&nbsp;&nbsp;the timeout interval.<br><br>Because the first argument is treated as a string, it's very difficult to see what's being evaluated.&nbsp;&nbsp;Generally when I use setTimeout I:<br>*&nbsp;&nbsp;build the string in a variable so if I have problems I can use an alert to display it and check it.<br>*&nbsp;&nbsp;use the string as the 1st agrumentof setTimeout, e.g. setTimeout(myString, interval);<br><br>Also because the first argument is treated as a string, on expiry of the timeout the browser does not remeber any object references (&quot;this&quot;)which were valid at the time of the setTimeout call.<br><br>So in the simplest case you have to hardcode the actual name of the variable which contains the object reference in the setTimeout call, e.g.<br>var myObj = new myObjType;&nbsp;&nbsp;// object constructor<br>myString = &quot;myFunc(myObj)&quot;;<br>setTimeout (myString, interval);<br>function myFunc(ObjName){<br>&nbsp;&nbsp;&nbsp;ObjName.width = x;<br>}<br><br>If you want to use myFunc on a range of object or to make the entire sequence of code whihc calls myFunc re-usable, things get trickier and you have to do something like:<br>function callMyFunc(ObjId, interval){&nbsp;&nbsp;// ObjId = STRING !!!<br>&nbsp;&nbsp;&nbsp;myString = &quot;myFunc(&quot; + myObj + &quot;)&quot;;<br>&nbsp;&nbsp;&nbsp;// This is where it's useful to be able to display<br>&nbsp;&nbsp;&nbsp;// myString, especially if you're also passing other<br>&nbsp;&nbsp;&nbsp;// arguments to myFunc&nbsp;&nbsp;-&nbsp;&nbsp;because getting the<br>&nbsp;&nbsp;&nbsp;///punctuation right is very tricky.<br>&nbsp;&nbsp;&nbsp;setTimeout (myString, interval);<br>}<br>function myFunc(ObjId){<br>&nbsp;&nbsp;&nbsp;// Here you have to use ObjId to find the required object<br>&nbsp;&nbsp;&nbsp;// see notes below.<br>&nbsp;&nbsp;&nbsp;ObjFound.width = x;&nbsp;&nbsp;// ObjFound represents the object.<br>}<br><br>There are various ways of using the string ObjId to find the actual object you want myFunc to process.<br>If the object is a standard one, e.g. an image:<br>*&nbsp;&nbsp;ObjId = image name<br>*&nbsp;&nbsp;myFunc says<br>&nbsp;&nbsp;&nbsp;document.images[ObjId].width = x;<br>If it's not a standard object, use the fact that you can create custom properties of any standard Javascript object, e.g.:<br>*&nbsp;&nbsp;document.ObjId = myObj; <br>*&nbsp;&nbsp;myFunc says<br>&nbsp;&nbsp;&nbsp;document.ObjId.width = x;<br>
 
Tonny9,<br><br>Ignore my last post and see the Tip I've just submitted.<br><br>I tried too hard to simplify something it took me a lot of work to solve, and my over-simplification contained lots of errors&nbsp;&nbsp;-&nbsp;&nbsp;sorry!<br><br>If you want to see proof that I have got this sort of stuff right:<br>* visit my website, <A HREF=" TARGET="_new"> click on &quot;Demos&quot; in the nav bar on the left.<br>* click on &quot;Office Assistant&quot;.
 
<br>philcha,<br><br>Thanks for your reply. I will try out your examples and see if it works. Regarding the &quot;this&quot; object. &quot;this&quot; from myFunc() refers to the class/constructor &quot;Test(int, int)&quot;. First I create a new object of the class/constructor &quot;Test&quot; like this:<br><br>var d = new Test(200, 300);<br><br>Then, in the actual constructor, the &quot;this.method&quot; is set it to point to the function &quot;myFunc()&quot; and that automatically makes &quot;myFunc()&quot; a member of the class/constructor &quot;Test(int, int)&quot;. So, the &quot;this&quot; inside the function &quot;myFunc()&quot;, refers to the &quot;this&quot; from &quot;Test(int, int)&quot; and because &quot;myFunc()&quot; automatically becomes member of &quot;Test(int, int)&quot;, the &quot;this&quot; from &quot;myFunc()&quot; references the same &quot;this&quot; from class/constructor &quot;Test(int, int)&quot;. So, &quot;this&quot; in &quot;myFunc()&quot; references the same object as &quot;this&quot; from class/constructor &quot;Test(int, int)&quot;. Currently that object would be the object where &quot;d&quot; points since I did: &quot;var d = new Test(200, 300)&quot;.<br><br><br>Beleive it or not but I almost &quot;gave up&quot; because setTimeout has caused me so many problems....Indeed, a person playing with setTimeout could have lots of fun, especially when it doesn't do what a person expects it to do :)). Thanks also for the URL...I will try your examples...<br><br>Regards:<br>Tonny9<br>
 
Tonny9, did you try to use Test.method() instead this.method? <p>IvanP<br><a href=mailto:ip@thehyper.net>ip@thehyper.net</a><br><a href= > </a><br>
 
<br>Ivanp,<br><br>No, I used this.method(). I am sure about it :) Really, I am sure.....<br><br>Regards:<br>Tonny9
 
Dear All,<br><br>The problem is that the window.setTimeout() method will not maintain the state of the object instance as Tony is trying to use it. In C++ terms, there is no this pointer inside the Test.method() call as the scripting engine treats it like a CALLBACK function.<br><br>So a solution is to use a proxy function that maintains the object instance in the global scope of the scripting engine (sort of what theEclipse was pointing out). I don't even know if that would make sense to me if I read it so here is what I mean in code. This was tested in IE5 on NT4.<br><br>&lt;SCRIPT LANGUAGE=javascript&gt;<br>&lt;!--<br>var oBase = null;<br><br>function onTimerProxy(){<br>&nbsp;&nbsp;if ( null != oBase)<br>&nbsp;&nbsp;&nbsp;&nbsp;oBase.onTimer();<br>}<br><br>function Base( name, mills){<br>&nbsp;&nbsp;this.name = name;<br>&nbsp;&nbsp;this.mills = mills;<br>&nbsp;&nbsp;this.count = 0;<br> <br>&nbsp;&nbsp;this.onTimer = base_ontimer;<br>&nbsp;&nbsp;this.setTimer = base_settimer;<br> <br>function base_ontimer(){<br> <br>&nbsp;&nbsp;this.count++;<br>&nbsp;&nbsp;alert( this.name + &quot;, &quot; + this.mills);<br>&nbsp;&nbsp;if ( this.count &lt; 4)<br>&nbsp;&nbsp;&nbsp;&nbsp;this.setTimer();<br>}<br> <br>function base_settimer(){<br>&nbsp;&nbsp;window.setTimeout( onTimerProxy, this.mills);<br>}<br> <br>this.setTimer(); // starts the timer the first time<br>} // class Base<br><br>function onBodyLoad(){<br>&nbsp;&nbsp;oBase = new Base(&quot;test&quot;, 500);<br>}<br>//--&gt;<br>&lt;/SCRIPT&gt;<br>&lt;/HEAD&gt;<br>&lt;BODY onload=&quot;onBodyLoad()&quot;&gt;<br><br>Hope this helps<br>-pete
 
<br>Dear <b>palbano</b> and the rest of you who tried to help<br><br>Thank you for replying and I appreciate it very much.<br><br><b>theEclipse</b>: Thanks for the idea.<br><b>palbano</b>: Thanks for the solution.<br><br>I will test it. If everything goes fine, I can finally complete my DHTML animation class.<br><br><br>Thank you all....<br><br>JavaScript sometimes might be a tricky language if you think in C++ as I did.....<br><br>Regards:<br>Tonny9
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top