SitePoint Sponsor

User Tag List

Results 1 to 11 of 11
  1. #1
    SitePoint Zealot
    Join Date
    Mar 2002
    Location
    Perth, Australia
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    HELP: SetTimeout from within a user-defined object

    Know if it's possible to execute a setTimeout using a function that is within a user-defined object?

    See my example code:

    function TestObj(theDiv){
    this.divObj = document.getElementById(theDiv);
    this.tester = function(){
    if(this.divObj.filters.alpha.opacity > 0){
    this.divObj.filters.alpha.opacity -= 5;
    window.setTimeout('this.tester()', 1);//causes problems
    }
    }
    }

    I know this doesn't work, but is there a way that does, along these lines? The reason it's wrapped as an object is because I intend to use many instances of the object at the same time.

  2. #2
    Currently Occupied; Till Sunda Andrew-J2000's Avatar
    Join Date
    Aug 2001
    Location
    London
    Posts
    2,475
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:

    <script>

        function 
    TestObj()
        { 
            
    tester = function()
            {
                if(
    this.filters.alpha.opacity 0)
                {
                    
    this.filters.alpha.opacity -= 5
                    
    window.setTimeout('tester()'1);//causes problems
                
    }
            }
        } 

    </script>


    When defining this why are you getting getElementById?

    Do you have the rest of the code so we can see what your trying to do exactly. 
    Last edited by Andrew-J2000; Apr 16, 2002 at 12:02.

  3. #3
    ********* obeah makeda's Avatar
    Join Date
    Jun 2001
    Location
    rollin' on dubs
    Posts
    492
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i don't understand your object reference to the function??? Try this:

    Code:
    function TestObj(theDiv){ 
      this.divObj = document.getElementById(theDiv); 
      
      //this sets up a reference
      this.tester = yourTestFunction;
    
      //if you want this to fire each time you instantiate object, try this:
      //this.tester = yourTestFunction();
    
      function yourTestfunction(){ 
        if(this.divObj.filters.alpha.opacity > 0){ 
          this.divObj.filters.alpha.opacity -= 5; 
          window.setTimeout('this.tester()', 1);//causes problems 
        } 
      } 
    }
    Not sure exactly what you're doing...
    Last edited by makeda; Apr 17, 2002 at 05:44.

  4. #4
    SitePoint Zealot
    Join Date
    Mar 2002
    Location
    Perth, Australia
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think that there is no way of getting around this with vanilla javascript; setTimeout is a method of the window object.

    This means that calling an object function within a setTimeout is out of context, resulting in an error.
    Last edited by peDey; Apr 17, 2002 at 00:58.

  5. #5
    Currently Occupied; Till Sunda Andrew-J2000's Avatar
    Join Date
    Aug 2001
    Location
    London
    Posts
    2,475
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I dont see why your calling a function within a function, but try something like this?

    PHP Code:

    <script language="javascript">
        
        function 
    TestObj(theDiv)
        {
            function 
    test(divObj)
            {
                if(
    divObj.filters.alpha.opacity 0)
                {
                    
    divObj.filters.alpha.opacity -= 5
                    
    window.setTimeout('test(divObj)'1);
                }
            }
            
            
    divObj document.getElementById(theDiv);
             
            
    test(divObj);
        }
        
    </script> 

  6. #6
    SitePoint Zealot
    Join Date
    Mar 2002
    Location
    Perth, Australia
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm calling a function within a function because it's an object constructor.

    I've got about 12 object instances that have exactly the same amount and type of properties. They each fade in increments to zero opacity when methods are called by 'onload' events within the web page.

    If all of the objects call a function outside of the generic constructor, they all rely on the same external function that controls the objects' opacity.

    This causes problems, because if an object calls the external function while it is being called by another object, then the function stops changing the opacity of the current object, and starts on the latest object that calls it.

    Alternatively, if the function is a method of the object constructor, then each object calls an instance of the opacity-changing method, not the same function, thus solving the problem of interrupted function calls.

    Unfortunately, setTimeout is only a method of the window object, and cannot be accessed by a user-defined object, because the setTimeout method is actually being called from within the user-defined object, and NOT from within the window object. This is made clear by changing the setTimeout method within the object constructor method to call a function that is outside of the constructor.

    Then the setTimeout method will work, but the old problem of the shared function returns. Try it.

    I am only a newbie to JavaScript objects, and would love to be proven wrong on this one, as my code would be a lot cleaner!

  7. #7
    ********* obeah makeda's Avatar
    Join Date
    Jun 2001
    Location
    rollin' on dubs
    Posts
    492
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it should work. I ran it and didn't get any errors. There were a few syntax errors with the code I posted before, should read like this:

    Code:
    function TestObj(theDiv){ 
      this.divObj = document.getElementById(theDiv); 
      
      //this sets up a reference
      this.tester = yourTestFunction;
    
      //if you want this to fire each time you instantiate object, try this:
      //this.tester = yourTestFunction();
    
      function yourTestFunction(){ 
        if(this.divObj.filters.alpha.opacity > 0){ 
          this.divObj.filters.alpha.opacity -= 5; 
          window.setTimeout('this.tester()', 1);//causes problems 
        } 
      } 
    }
    I commented out the lines with filters.opacity and just ran some other code with alert boxes and it worked fine. No errors, which means that i was able to use the setTimeout method in my user defined object.

    P.S. tested on IE6

  8. #8
    SitePoint Zealot
    Join Date
    Mar 2002
    Location
    Perth, Australia
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    makeda,

    if you call the code as a function and not an object, you won't get any errors. But only the last function call will work.

    If you create a series of new objects based on the object constructor, then you will get errors.

    This is what I mean:

    <script language="JavaScript">
    function TestObj(theDiv){
    this.divObj = document.getElementById(theDiv);

    //this sets up a reference
    this.tester = yourTestFunction;
    this.tester();

    //if you want this to fire each time you instantiate object, try this:
    //this.tester = yourTestFunction();

    function yourTestFunction(){
    if(this.divObj.filters.alpha.opacity > 0){
    this.divObj.filters.alpha.opacity -= 25;
    window.setTimeout('this.tester()', 40);//causes problems
    }
    }
    }
    </script>

    <div id="test" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test2" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test3" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>


    <script language="JavaScript">
    // now call the TestObj function for each DIV:
    TestObj('test');
    TestObj('test2');
    TestObj('test3');// Only this function will get the chance to finish

    </script>

    Okay, now the code for an object-based approach
    (yourTestFunction modified to treat this.divObj value as an object):

    <script language="JavaScript">
    function TestObj(theDiv){
    this.divObj = document.getElementById(theDiv);

    this.tester = yourTestFunction(this.divObj);

    function yourTestFunction(theObj){
    if(theObj.filters.alpha.opacity > 0){
    theObj.filters.alpha.opacity -= 55;
    window.setTimeout('this.tester()', 40);//causes problems
    }
    }
    }
    </script>

    <div id="test" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test2" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test3" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>


    <script language="JavaScript">
    // now call the TestObj function for each DIV:
    objInstance1 = new TestObj('test');
    objInstance2 = new TestObj('test2');
    objInstance3 = new TestObj('test3');
    </script>

    this returns an error only because of the method called within the setTimeout function.
    comment out the line that includes:
    window.setTimeout('this.tester()', 40);//
    and each object will lose their 1st increment of opacity, but obviously won't loop to finish the job off.

  9. #9
    ********* obeah makeda's Avatar
    Join Date
    Jun 2001
    Location
    rollin' on dubs
    Posts
    492
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    very confusing....when i tested it, i created an onload function which would instantiate 3 versions of the object. i'll look at it some more when i have time...

  10. #10
    SitePoint Zealot
    Join Date
    Feb 2002
    Location
    UK
    Posts
    146
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    this may point you in the right direction - i cobbled it together from something similar
    at dhtmlCentral, see: http://www.dhtmlcentral.com/script/script.asp?id=10

    see also: http://freewarejava.com/ubb/Forum1/HTML/022452.html


    Hopefully a better javascript coder can have a look at this, as i'm sure there are mistakes.

    the key seems to be the lines:
    Code:
    this.obj = id + "Object"
    eval(this.obj + "=this");
    creates a reference to the object that you can use for setTimeout.

    hope this helps a bit

    Code:
    <html>
    <head>
    <script language="JavaScript">
    
    function TestObj(id){
    
    	this.css = document.getElementById(id);
    	this.obj = id + "Object"
    	eval(this.obj + "=this");
    
    	this.tester=yourTestFunction;
    
    	//call tester function
    	this.tester();
    }
    
    function yourTestFunction(){
    
    	this.css.filters.alpha.opacity -= 5;
    	if (this.css.filters.alpha.opacity > 0)
    		setTimeout(this.obj+".tester();",50);
    
    }
    
    </script>
    </head>
    
    <body>
    <div id="test1" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test2" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    <br>
    <div id="test3" style="width:100px;height:100px;background:red;filter:alpha(opacity=100)"></div>
    
    <script language="JavaScript">
    // now call the TestObj function for each DIV:
    objInstance1 = new TestObj('test1');
    objInstance2 = new TestObj('test2');
    objInstance3 = new TestObj('test3');
    </script>
    
    </body>
    </html>

  11. #11
    SitePoint Zealot
    Join Date
    Mar 2002
    Location
    Perth, Australia
    Posts
    164
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Talking

    Martm - perfect! Your code works a treat.

    Thanks to everyone for their input; I've learnt a lot from this exercise. I'll post the URL of the site that I'm using this code on when it's ready, so one can see the end result if interested.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •