Jump to content
GreenSock

Aleksei

GSAP doesn't work with innerHTML

Recommended Posts

Hello!

I've found a strange behavior of TweenMax while using it together with innerHTML.

Ceck the codepen below for live example.

 

 

The problem is that I want to move an existing element inside some wrapper. And at the same time I want insert new elements via innerHTML into the same wrapper.

 

This code won't work:

function move() {
  TweenMax.to('#animate_me', .5, { x: 100 });
}

move();
wrapper.innerHTML += '<div id="new_guy">New Guy</div>';

But this one will work:

function move() {
  TweenMax.to('#animate_me', .5, { x: 100 });
}

wrapper.innerHTML += '<div id="new_guy">New Guy</div>';
move();

Pay attention on lines 5 and 6.

Does anybody know what causes this problem?

Personally I don't understand why the existing element can't be animated inside the wrapper where you use innerHTML. None of the objects inside wrapper can be animated if innerHTML works there. But why?

 

See the Pen wJGova by jonathan (@jonathan) on CodePen

Link to comment
Share on other sites

Herllo Aleksei,

GSAP does work with innerHTML. ;) The reason your example is not working is that you are using the same id for two different elements.

Your trying to target an element that doesn't exist in the Dom yet. So you would need to use a DOMContentLoaded event to run code after DOM is ready.

In HTML the id attribute must be unique for each element. When used in JS the id shares the same global namespace in the window object as the name attribute. And browsers will sometimes silently fail when trying to reference multiple elements with the same id inside the DOM and global namespace. So if you want consistent cross browser behavior always make id's unique, and the browser will find the element.
 

The id attribute must be unique for each element. Please see the spec(s):

WHATWG: https://html.spec.whatwg.org/multipage/browsers.html#named-access-on-the-window-object

W3C: https://www.w3.org/TR/html401/struct/global.html#h-7.5.2

The Window object supports named properties. The supported property names of a Window object window at any moment consist of the following, in tree order according to the element that contributed them, ignoring later duplicates:

Happy Tweening!

  • Like 3
Link to comment
Share on other sites

Jonathan, Sorry for the misleading. These ids is my rough mistake. But the problem is actually remains. I've changed id to class and the problem described above is still there: 

See the Pen MpyeYP by nordskill (@nordskill) on CodePen

 

P.S. I even changed wrapper id to class. Just in case.

Link to comment
Share on other sites

The problem is that when move() is called, the selector addresses both elements ... but, in the case of the one being wrapped, the DOM has changed after that element was referenced (and is now gone).

  • Like 3
Link to comment
Share on other sites

[was typing this while Shaun was typing too...basically saying the same thing...]

 

When you set innerHTML, it completely obliterates any HTML elements that were previously in that HTML, and replaces it with new stuff that the browser parses fresh. So when you created your tween, ".animate_me" referred (in part) to that element inside the container. Perfect. BUT as soon as you replaced innerHTML, it dumped that element out of the DOM and created an entirely NEW one. That object reference is totally different now. So the thing that was tweening is not the new thing you just added via innerHTML. 

 

Does that make sense?

 

If you want to keep animating that same element, don't kill it by editing innerHTML - instead, alter your DOM with methods like appendChild(). 

  • Like 5
Link to comment
Share on other sites

Your trying to target an element that doesn't exist in the Dom yet. So you would need to use a DOMContentLoaded event to run code after DOM is ready. or just use the working GOOD example in your first post.

  • Like 3
Link to comment
Share on other sites

Thank you, guys! Now that's clear. 

I though that += operator doesn't change the content and works like appendChild(). But of course that's not true. The string variable is changed.

Thanks again!

  • Like 1
Link to comment
Share on other sites

Ah, very strange. Thanks for the clear demo. Haven't seen this before. I don't think it's necessarily a GSAP issue.

 

According to this: http://stackoverflow.com/a/595825 using innerHTML to add elements can somehow mess up child elements in the same parent 

 

Here is a quick test using jQuery's append() to add the new_guy element and it works fine: http://codepen.io/GreenSock/pen/gmrgGG?editors=0010

 

So use that or the vanilla js way of creating new elements https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement

  • Like 3
Link to comment
Share on other sites

I guess I should check that no one else figured this out first ;) some of you guys are fast!

  • Like 4
Link to comment
Share on other sites

I guess I should check that no one else figured this out first ;) some of you guys are fast!

Now you know how we feel in an answer battle with you.  :D

  • Like 4
Link to comment
Share on other sites

Wow! insertAdjacentHTML solves the problem and does exactly what I meant when thought about += with innerHTML.

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