Jump to content
Search Community

Can't access any objects from a timelinemax callback!

bobdobbs test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I'm in the process of creating a functions to create a slideshow.

 

my variable 'slides' is a jquery object, containing dom elements that will be my slides.

I pass 'slides[1] to my timeline function.

I'd like to use the onComplete callback to increment the value of currentSlide, and then repeat the animation.

 

However, I discovered that I couldnt' access the variable currentSlide from the callback.

Doing a little poking around, I found that I couldn't access any objects from the callback.

 

Is this expected behaviour? Or am I doing something wrong?

 

My code:

  var slides =       window.myApp.slides ;  // returns a jQurey object
  currentSlide =     window.myApp.slides[1] ;
 
    var tl = new TimelineMax() ;
    tl.to( currentSlide, 2,
           { left : 0,
             onComplete : completeHandler
           }
         ) ;
} // this function does work. An animation occours

function completeHandler (){ 
    console.debug( "next slide: " . slides[2] ); // returns undefined.
}
Link to comment
Share on other sites

It looks like you've got some syntax errors in your code. You had an extra end brace ("}") and you used a period instead of a + for concatenation in your console.debug(). 

 

I just tried this code and it worked great:

var slides = ["#test1","#test2","#test3"] ;
var currentSlide = slides[1] ;
var tl = new TimelineMax() ;
tl.to(currentSlide, 2,
			{ left : 0,
			  onComplete : completeHandler
			}
	);

function completeHandler() {
	console.log( "next slide: ". slides[2] );
};
Link to comment
Share on other sites

If I'm reading it correctly, it seems like you might have your code setup something like this:

function changeSlide() {
  var slides = window.myApp.slides;  // returns a jQuery object
  currentSlide = window.myApp.slides[1];

  var tl = new TimelineMax();
  tl.to( currentSlide, 2,
    {
      left: 0,
      onComplete: completeHandler
    }
  );
} // this function does work. An animation occurs

function completeHandler (){ 
  console.debug( "next slide: " + slides[2] ); // returns undefined.
}

The problem with this is that var slides is only within changeSlide()'s scope. Since slides is not accessible from completeHandler, slides will be 'undefined' in that scope.

 

If you want to access a variable from within a callback that isn't within the same scope, you can pass extra parameters with your callback. In this case you can use onCompleteParams:

function changeSlide() {
  var slides = window.myApp.slides;  // returns a jQuery object
  currentSlide = window.myApp.slides[1];

  var tl = new TimelineMax();
  tl.to( currentSlide, 2,
    {
      left: 0,
      onComplete: completeHandler,
      onCompleteParams: [slides]
    }
  );
} // this function does work. An animation occours

function completeHandler (slides){ 
  console.debug( "next slide: " + slides[2] );
}

Also, defining the onComplete inline would give it access to the changeSlide() scope and the slides var:

function changeSlide() {
  var slides = window.myApp.slides;  // returns a jQuery object
  currentSlide = window.myApp.slides[1];

  var tl = new TimelineMax();
  tl.to( currentSlide, 2,
    {
      left: 0,
      onComplete: function (){ 
        console.debug( "next slide: " + slides[2] );
      }
    }
  );
} // this function does work. An animation occours

Check out the top answer here for a crash course on variable scope. A quick google for 'javascript variable scope' will likely yield some more informative results as well.

Link to comment
Share on other sites

Hey Jack.

 

I still can't quiet get it to work. It seems as if any references to the global scope fail, and execution then stops.

 

for example, this works as expected:

  
 var slides =       window.chickenSliderApp.slides ; // returns a jquery object
 currentSlide =     window.chickenSliderApp.slides[1] ;

            var tl = new TimelineMax() ;
            tl.to( currentSlide, 2,
                   { left : 0,
                     onComplete : function (){
             console.debug("in onComplete" ) ;

             }
                   }
                 ) ;

In this case, I can see "in onComplete" printed to the console.

However, this fails, and console prints 'undefined', and execution stops without "in onComplete" being printed:

 var slides =       window.chickenSliderApp.slides ; 
 currentSlide =     window.chickenSliderApp.slides[1] ;

            var tl = new TimelineMax() ;
            tl.to( currentSlide, 2,
                   { left : 0,
                     onComplete : function (){
             console.debug("in onComplete. Current slide:  " . currentSlide ) ;

             }
                   }
                 ) ;
Link to comment
Share on other sites

Hey Jamie.

 

Thanks for pitching in.

 

I guess I expect the callback to have access to the members of it's parent, because it's an inner function. My expectation is that inner functions can access the state of the parent.

What I found particularly confusing in my testing was this: 'window' is coming back as undefined.

 

For the moment, I put the callback inline. And it still doesn't seem to be able to access the parents data. Currently I have this:

var slides =       window.chickenSliderApp.slides ;
currentSlide =     window.chickenSliderApp.slides[1] ;

            var tl = new TimelineMax() ;
            tl.to( currentSlide, 2,
                   { left : 0,
                     onComplete :  function completeHandler (){
                           console.debug( "in completeHandler" );
                           console.debug( "slide: " . slides[0] );           
             }             
           }
                 ) ;

Again, the animation actually happens. However, the script halts execution on the second debug line of the callback, with the error:

 

"Uncaught TypeError: Cannot read property '0' of undefined"

I created another test, using onCompleteParams as well an inline onComplete callback:

var slides =       window.chickenSliderApp.slides ;
currentSlide =     window.chickenSliderApp.slides[1] ;

var tl = new TimelineMax() ;
            tl.to( currentSlide, 2,
                   { left : 0,
             onCompleteParams: slides,
                     onComplete :  function completeHandler (){
             console.debug( "in completeHandler" );
             console.debug( "slide: " . slides[0] );           
             },
             
           }
                 ) ;

I get a similar result: "Uncaught TypeError: Cannot read property '0' of undefined".

 

I'm reading that article on scope presently.
 

Link to comment
Share on other sites

Oh, darnit!

I didn't know about the string concatenation symbol!

I have now idea how I got this far without knowing this!

 

Thanks for pointing this out.

I'm now getting something back from the onCompleteHandler. Console prints:

slide: [object HTMLDivElement]

This is still unexpected: I'm expecting an object to be dumped. Instead it looks like I'm getting a description of the object. So I'm not sure if I'm passing in an object to onComplete, or passing in something else. So confusing!

 

Still confused. But it looks like I'm making progress :)

Link to comment
Share on other sites

Ok just a few things:

onCompleteParams: slides
needs to be

onCompleteParams: [slides]
as onCompleteParams requires that you pass it an array of parameters (even if there is only one)

 

It does seem like you have access to your slides object now. When you call

console.debug( "slide: " + slides[0] )
what you are doing is essentially

console.debug( "slide: " + slides[0].toString() )
( [object HTMLDivElement] is just the string representation of slides[0] )

 

If you are using Firebug and want the awesome dynamic object links, separate the things you are logging with commas. console functions usually take multiple parameters, and each parameter will get treated as its own object rather than a single string in the console e.g.

console.debug( "slide:", slides[0] );
  • Like 3
Link to comment
Share on other sites

Hey Jamie.

 

Thanks again! That makes my result make so much more sense to me.

 

Also thanks for letting me know about logging with commas. This seems to work in chrome as well firefox. I had no idea about this before, and it is massively helpful.

 

If you have the patience, I've got one last question: Am I taking the right approach to creating a slideshow?

 

You might already be able to tell: I'd like to use the callback to increment an index. currentSlide will be incremented, and the new slide will then be animated. After every slide is animated, the sequence will be repeated using the 'repeat' property.

 

Is this a sensible approach to take?

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...