Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
kbeats

Use one function to apply one timeline to multiple div's via ID containing specific word

Recommended Posts

I've been banging my head against the wall on this one for a while now. My goal is to have one function that will apply to any div whose id contains the word 'image' (I realize it would probably be easier to do this by class name, but I'm hoping to use this code in an Adobe Captivate project, where I know how to get the ID of images, but not the class). I've tried several different ways, but I keep running into the same issue - whenever I get it to work, it will run well the first time I click a div (by only targeting the div that is clicked), but as soon as I click a different div it will run the function on both of them. I've tried every iteration of this and $(this) I can think of, but can't get it right. 

 

See the Pen qJjpqP by kbeats (@kbeats) on CodePen

I have a couple of commented out attempts in this codepen, but my most recent attempt looks like: 

 

var target = this.$("div[id*=\"image\"]");
    for (var i=0;i<target.length;i++){
      target[i].addEventListener("click", function() {
        tl.to(this, .6, {x:100, y:100}, 0);
        tl.reversed() ? tl.play() : tl.reverse();
      })
    }

 

I'm trying to loop through the variable I've defined as any div with an id containing the word "image", but even with the loop it's still affecting both divs when only one is clicked? I'm really confused as to why this is happening, I thought the entire point of a for loop is to target just one object within the loop? 

 

Is there something I need to add into an onComplete function that breaks up the loop? 

See the Pen qJjpqP by kbeats (@kbeats) on CodePen

Link to comment
Share on other sites

Hi @kbeats, the issue I see is that you are appending to the same timeline and playing/reversing that timeline. That's why they get added together. Give this a try,

 

See the Pen MPoGVj by sgorneau (@sgorneau) on CodePen

 

  • Like 4
Link to comment
Share on other sites

Thank you Shaun! This is super helpful and exactly what I was trying to do!

 

I don't really understand the line: 

 

if (!window[id]) {

window[id] = new TimelineMax({paused:true, reversed:true});

 

Is this just saying if there is no div id selected it will create a new timeline and store it in a variable window[id]? 

 

I'm trying to understand as much as possible so if I need to I can build off this in the future. 

Thanks! 

 

 

Link to comment
Share on other sites

Looks like Shaun has you all fixed up, but here's a slightly different approach just in case you need options.

 

See the Pen MPoXrQ by PointC (@PointC) on CodePen

Happy tweening.

:)

 

  • Like 3
Link to comment
Share on other sites

2 hours ago, kbeats said:

Thank you Shaun! This is super helpful and exactly what I was trying to do!

 

I don't really understand the line: 

 

if (!window[id]) {

window[id] = new TimelineMax({paused:true, reversed:true});

 

Is this just saying if there is no div id selected it will create a new timeline and store it in a variable window[id]? 

 

I'm trying to understand as much as possible so if I need to I can build off this in the future. 

Thanks! 

 

 

 

Hi @kbeats, because we need each block to be controlled by its own timeline, we can't keep recreating 

 

var tl = new TimlineMax()...

 

Because we'll just keep overwriting the `tl` ... potentially reversing the wrong timeline. So, we need dynamic variable names to hold the timelines. In PHP, we can do cool things like

 

<?

$something = 'foo';

$$something = 'bar';

print $foo; // -> bar


// we can also do

$i = 1;
${'something_'.$i} = 'Green';
$i++;
${'something_'.$i} = 'Sock';

print $something_1.$something_2; // -> GreenSock

 

 

In Javascript, we're not so fortunate with the variable variables. But, in the global scope, when assigning

 

var a = 1;

 

we can get to the value of `a` with any of the following ...

 

console.log( a );
console.log( window.a );
console.log( window['a'] );

 

So, seeing as `a` is a property of the window object (in the global scope), we see how variables can be declared that way too. Dot syntax doesn't help construct a variable variable because we can't use an expression for the property ( e.g. this.'something'+i just doesn't work )

 

But arrays allow strings as key values ... so we can use an expression there ( e.g. this['something_'+i] ). Soooooo,

 

var tl = new TimelineMax();

 

Is the same as stating

 

window.['tl'] = new TimelineMax();

 

 

which means 

 

var i = 0;
window.['tl_'+i] = new TimelineMax();

i++;

window.['tl_'+i] = new TimelineMax();

 

is perfectly valid for creating dynamic variable names .. and we now have

 

tl_1; // a TimlineMax object

tl_2; // another TimelineMax object

 

 

and, in terms of

 

if (!window[id]) { ...

 

I'm just checking to see if it's been defined. If not, create the Timeline and control it. If yes, don't recreate the timeline, just control it.

 

Hope this helps!

 

 

EDIT *** After rereading ... I don't want to ignore what would be done within a function (i.e. not in the global scope)

 

If we do the following ..

 

var a = 1;

function something(){
  
  var a = 2;
  console.log( a );
}

something();

console.log( a );

 

The console would show

 

2
1

 

because when something() is called, it in itself has a console.log which references the `a` in the local scope, outputting 2 ... and then the other console.log is called after that referencing the `a` in the global scope, outputting 1.

 

But, we can create variable variables within the function just like I did above by declaring in the window object to then be addressable directly in the global scope or anywhere as a property of window. But if we just need variable variables within the scope of a function, we can also do 

 

function something(){
  
  var i = 0;
  
  this['tl_'+i] = new TimelineMax();
  
  i++;
  
  this['tl_'+i] = new TimelineMax();
  
  // creating variables `tl_0` and `tl_1` within the scope of the function
  
}

 

 

  • Like 5
Link to comment
Share on other sites

Thank you so much Shaun for taking the time to explain this! It's all still a bit over my head, but I'm trying to learn as much as I can and this is extremely helpful! 

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.
×