Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    Regular Coder
    Join Date
    Mar 2007
    Posts
    357
    Thanks
    46
    Thanked 22 Times in 21 Posts

    Question setTimeout and Objects

    I'm sure it's been brought up before, but this problem is pretty code specific so. Lets go, so. Calling setTimeout inside an object doesn't work due to the this points being different etc etc. My problem is that, setTimeout doesn't seem to work until the function has been called multiple times. Here's the code first:

    Code:
    function textObject( txtPtr ) {
       this.text = txtPtr;
       this.fadeVal = 0;
       this.doFade = 0;
       this.fadeOut = function() {
          var gObj = this;
          if( this.doFade == 0 ) {
             this.fadeVal = 1;
             this.doFade = 1;
             setTimeout( gObj.fadeOut, 500 );
          } else {
             if( this.fadeVal <= 0 ) {
                this.text.style.opacity = 0;
                return 0;
             }
             this.fadeVal = this.fadeVal - 0.04;
             this.text.style.opacity = this.fadeVal;
             setTimeout( gObj.lolErt, 50 );
          }
       }
       return true;
    }
    And heres a snippet of HTML I'm using:

    <span onclick="OBJ.fateOut()">Click me</span>

    I've been placing alerts()'s after each line to see whether the code is being executed, if I place alert() in the } else { section (which should be entered after 500 miliseconds) and then click. After 500 mili seconds, as expected. It alerts me. This means that the setTimeout is infact working. However, the second timeOut doesn't work. No matter what. I have to manually click the text over and over again in order for it to loop. So this means that it isn't working.

    I placed an alert after the second setTimeout, and something weird happened. The first time I click the text, the alert appears. Then doesn't appear again, so that means the first timeout worked as before, but the second didn't and so it isn't looping. So I click again, this time the alert shows, and immediately another alert shows. So it looped once.. then not again. Why is this?

    Sorry for long post. I know I could easily solve this by using a loop, and I probably will use a loop after this, but now that I've found this problem, I would like to know what is causing it.

    Edit:

    There shouldn't be anything wrong with the function, I just rewrote as a normal function, couple of differences but nothing that should change whether it works or not (user global variables and parameters instead of class parameters.) but this works.

    Code:
    var fadeCount = 0;
    var textStore = 0;
    
    function fadeText( txtPtr, doFade ) {
       if( doFade == 0 ) {
          textStore = txtPtr;
          fadeCount = 1;
          setTimeout( "fadeText( 0, 1 )", 500 );
       } else {
          if( fadeCount <= 0 ) {
             textStore.style.opacity = 0;
             return 0;
          }
          fadeCount = fadeCount - 0.04;
          textStore.style.opacity = fadeCount;
          setTimeout( "fadeText( 0, 1 )", 50 );
       }
    }
    Last edited by flynch01; 10-02-2008 at 12:52 AM.

  • #2
    Banned
    Join Date
    May 2006
    Location
    England
    Posts
    664
    Thanks
    0
    Thanked 84 Times in 84 Posts
    Quote Originally Posted by flynch01 View Post
    I'm sure it's been brought up before, but this problem is pretty code specific so. Lets go, so. Calling setTimeout inside an object doesn't work due to the this points being different etc etc. My problem is that, setTimeout doesn't seem to work until the function has been called multiple times.
    I don't see any attempt to create an object instance. To refer to an object instance in setTimeout, you can use a function closure as shown in the example below. I suggest you read up on JavaScript objects and closures.

    I'm not sure exactly what your intended functionality was, but this example fades once then resets:
    Code:
    <html>
     <head>
      <title> New Document </title>
     </head>
     <body>
      
    <span id='t1'>THIS IS TEXT</span> 
     
    <script type="text/javascript">
    
    
    function TextObject( txtPtr ) 
    {
     this.text = txtPtr;
     this.fadeVal = 1;
     this.doFade = 0;
     
     this.fadeOut = function() 
     {
       if( this.doFade == 0 ) 
       {
         setTimeout( ( function(obj){ return function(){ obj.fadeOut(); } } )(this), 200 );
             
         this.fadeVal -= 0.04;
             
         if( this.fadeVal <= 0 )
         {
           this.fadeVal=0;
           this.doFade=1;
         }    
             
         this.text.style.opacity = this.fadeVal; 
       }
       else 
         this.text.style.opacity = 1;
     }          
     
    }
    
    new TextObject( document.getElementById('t1') ).fadeOut();
    
    </script>
     
    </body>
    </html>

  • Users who have thanked Arty Effem for this post:

    flynch01 (10-02-2008)

  • #3
    Regular Coder
    Join Date
    Mar 2007
    Posts
    357
    Thanks
    46
    Thanked 22 Times in 21 Posts
    I figured I didn't have to quote the instance, because I said that the function was executing. But here, if this is what you meant anyway:

    <span onclick="createOBJ(this)">Create OBJ</span>

    and the function, unneeded but for cleanliness

    Code:
    var OBJ = 0;
    function createOBJ( Ptr ) {
        OBJ = new textObject( Ptr );
    }
    Anyway thanks, I'll try it now. If I have problems I'll post back.

    Edit: Intended functionality was delayed fade. Waits 500 seconds then fades the text till it's invisible.
    Last edited by flynch01; 10-02-2008 at 03:57 AM.

  • #4
    Regular Coder
    Join Date
    Jun 2007
    Location
    USA
    Posts
    527
    Thanks
    26
    Thanked 74 Times in 72 Posts
    Try this. Not sure if it works. (I just did a little cleaning.)

    Code:
    Function.prototype.bundle = function(context) {
      Array.prototype.slice.call(arguments, 1, 0, this);
      return Function.bundle.apply(null, arguments);
    };
    
    
    function TextObject(textEl) {
      this.text = textEl;
      this.fadeVal = 0;
      this.doFade = true;
    }
    
    TextObject.prototype = {
      fadeOut: function() {
        if(this.doFade) {
          this.fadeVal = 1;
          this.doFade = false;
          setTimeout(this.fadeOut.bind(this), 500);
          return;
        }
        if(this.fadeVal <= 0) {
          this.text.style.opacity = 0;
          return;
        }
        this.fadeVal -= 0.04;
        this.text.style.opacity = this.fadeVal;
        setTimeout(this.fadeOut.bind(this), 50);
      }
    };
    Trinithis

  • Users who have thanked Trinithis for this post:

    flynch01 (10-02-2008)

  • #5
    Regular Coder
    Join Date
    Mar 2007
    Posts
    357
    Thanks
    46
    Thanked 22 Times in 21 Posts
    Wow thanks. I'd rather not use something that I don't understand though. Thanks still though But, I do have a problem with this. This is what I have:

    Code:
    var ObjectAr = new Array();
    var ThankAr = new Array('Someone','Sometwo','Somethree');
    var ObjectCt = 0;
    
    function textObject( txtPtr ) {
       this.text = txtPtr;
       this.fadeVal = 0;
       this.doFade = 0;
       this.fadeOut = function() {
          var gObj = this;
          if( this.doFade == 0 ) {
             this.fadeVal = 1;
             this.doFade = 1;
             setTimeout( ( function(obj){ return function(){ obj.fadeOut(); } } )(this), 600 );
          } else {
             if( this.fadeVal <= 0 ) {
                this.text.style.opacity = 0;
                return 0;
             }
             this.fadeVal = this.fadeVal - 0.04;
             this.text.style.opacity = this.fadeVal;
             setTimeout( ( function(obj){ return function(){ obj.fadeOut(); } } )(this), 50 );
          }
       }
       return true;
    }
    function addObj( Ptr ) {
       if( Ptr.onclick != undefined ) return;
       ObjectAr[ObjectCt] = new textObject( Ptr );
       var newClick = function() {
          ObjectAr[ObjectCt-1].fadeOut();
          Ptr.innerHTML = ThankAr[Math.floor(Math.random()*ThankAr.length)];
       }
       Ptr.onclick = newClick;
       ObjectCt = ObjectCt + 1;
    }
    Here's the HTML. The reason I used objects in the first place was so multiple elements wouldn't overwrite the fadeout code. So if you look here:

    <a onmouseover="addObj(this)">Test1</a> <a onmouseover="addObj(this)">Test2</a> <a onmouseover="addObj(this)">Test3</a>

    The idea is that. It adds each object to the Object array, so that they're all actually stored somewhere. Each time one is created ObjectCt is incremented so that the next object is stored higher in the array.

    Problem is, newClick is being set to onClick, and instead of each html elements onclick having a seperate ObjectCt, it seems to overwrite. So like.

    If I click Test1, then Test2, then Test3. They will fade on their own perfectly. But, if I Click Test1, scroll my mouse over Test2, then scroll over Test3, then click on 2. Test3 will fade.

    The reason I know is because, once I've rolled over, the undefined if makes sure that it can't set again. I did this because if I didn't do this, I could make the other objects flicker by quickly clicking each one alternating between them. So the problem is that once I scroll over Test3, it sets the function in newClick to point to the latest object. And all the Tests are pointing to the same function. I tried creating the function and then putting it inside the individual classes. But that didn't work.
    Last edited by flynch01; 10-02-2008 at 06:09 AM.


  •  

    Posting Permissions

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