Jump to content
Search Community

Live jQuery Elements

anteksiler 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

The first idea that come up in my mind is to target your elem through something that already exists.

If you are using jQuery, you could try:

TweenLite.to($('body').find('.your-elem'), 1, {top: "30px"});

For sure this is not the most optimize solution but I'm newbie in gsap and maybe you have to check is the lib has update method or supports triggering custom events.

Link to comment
Share on other sites

It sounds very much like the element is becoming dereferenced. This usually happens when you modify innerHTML that contains the element. Even though the element may still 'exist' after the modification, any references to it are lost and new ones must be made. You're probably going to have to reconsider how the side-cart is updated, or rebuild your tweens when you do so.

 

It becomes quite time consuming to investigate a complex site like this so it's difficult to allocate enough time to dive into your full project. Please consider creating a reduced Codepen demo that shows the issue so we can resolve it quickly.

Link to comment
Share on other sites

This is my code:

var MainCart = new TimelineMax({
    paused: true,
    onStart: function() {
        $('#side-cart').css('display', 'block');
    },
    onReverseComplete: function() {
        $('#side-cart').css('display', 'none');
    }
});

MainCart
    .add(TweenLite.to($('#side-cart'), 0.5, {
        autoAlpha: 1,
        ease: Quart.easeOut
    }))
    .add(TweenLite.to($('#side-cart').find('#cart-container'), 0.5, {
        x: 0,
        ease: Quart.easeOut
    }))
    .add(TweenMax.staggerFrom($('#side-cart').find('.item'), $('#side-cart').find('.item').length * 0.1, {
        y: "50",
        opacity: 0,
        ease: Quart.easeOut
    }, 0.1));

What I am thinking is, I should kill the MainCart animation completely and re-create it everytime the ajax runs. Is this correct?

Link to comment
Share on other sites

Yea that code doesn't give much of a picture of what's actually going on (it's just tweens, not what's interfering with them). Here's two examples to show the behaviour I think you're seeing

 

Correct: 

See the Pen ogBOOV by jamiejefferson (@jamiejefferson) on CodePen

 

Incorrect: 

See the Pen zxNXXa by jamiejefferson (@jamiejefferson) on CodePen

 

If the page is being modified in the "incorrect" way, then the tween has lost it's reference and can't be used anymore. You will need to create new tweens of the new elements to replace it.

  • Like 4
Link to comment
Share on other sites

Like I told you, I cannot change the way AJAX works.

 

The only way for me to fix this is to detect the dereferencing and create a new animation.

 

But to answer your question, they are using jQuery's ReplaceWith():

https://github.com/woothemes/woocommerce/blob/0accdf6f10b19c59e4a517b1401bd8519a11fc17/assets/js/frontend/add-to-cart.js#L87

Link to comment
Share on other sites

Jamie,

 

Thanks for providing the super clear demos. I'm sure others will find them useful in the future. I love how they clearly show how easy it is to illustrate the problem without using AJAX or WooCommerce's exact script.

 

And, yes, Antesiler, it looks like you will have to create new animations.

Link to comment
Share on other sites

Not really sure exactly what you want to do.

I am assuming that you want to start an animation on a selected element, create new elements based on the same selector string, and smoothly continue the originally animation with the addition of the new elements.

 

Since I can only work with Jamie's code, this is how I would do it:

 

// add the tween we want to always run
var master = TweenLite.to("#element1", 3, { opacity: 0 })


// before that tween completes, let's "break" the reference
TweenLite.delayedCall(1, function() {
  var c = $("#container"),
      innerhtml = c.html(); // THIS IS JUST A STRING
  
  c.append("<div id='element1' class='element'></div>");
  
  //figure out the time of the animation
  var time = master.time();
  //rewind to time(0) and kill()
  master.time(0).kill();
  //create new tween
  master = TweenLite.to(".element", 3, { opacity: 0 })
  //jump ahead to recorded time
  master.play(time)
  
  // Since .append() uses the correct DOM methods to attach a new node, the original elements have not been replaced and the tween continues unaffected.
})

 

http://codepen.io/GreenSock/pen/zxNQjX

 

--

 

As far as what exactly kill() does to the children, I'll get you a more precise answer

  • Like 1
Link to comment
Share on other sites

Interestingly, I solved this by assigning the animation to the window element by:

var window.MainCart = new TimelineMax({
    paused: true,
    onStart: function() {
        $('#side-cart').css('display', 'block');
    },
    onReverseComplete: function() {
        $('#side-cart').css('display', 'none');
    }
});

Is there any reason I shouldn't be doing this?

Link to comment
Share on other sites

Does the kill() allow me to remove the children from "MainCart" variable? What's the preferred method or what would you do in this scenario?

 

 

Killing does not remove children. To remove the children from the timeline use MainCart.clear().

 

I'm glad you found a solution. I'm not exactly sure how it solves the problem of tweening while the DOM is being modified, but it sounds like its good.

  • Like 2
Link to comment
Share on other sites

Hello, To add to these fine gents great advice.. Not sure if this will help!

 

But It sounds like ajax is removing those elements and like Jamie said it is becoming deferenced. So since you are using jQuery as your selector $('#side-cart'), you can pass the context so jQuery knows the parent that is in context of your passed selector. Even if the element is removed from the DOM. So for example:

:

// so this 
$('#side-cart')

// would become this using context
// jQuery( selector [, context ] )
$('#side-cart', '#parent-of-side-cart1')

// or you can use the jQuery find() method
// so your main selector is above the DOM elements you are adding and removing
$('#parent-of-side-cart1').find('#side-cart');

:

Or you can use the jQuery find() method, so your main selector is above the DOM elements you are adding and removing below your main selector.

 

You can also setup jQuery global AJAX event callbacks so you know when the AJAX completes, and has success callback. And it doesn't require you touching the AJAX.. you just setup AJAX events to listen for complete, success, xhr, and errors.
 

Reference:

 

.find( selector )

jQuery( selector [, context ] )

Global Ajax Event Handlers

 

I hope this helps :)

  • Like 2
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...