Jump to content
Search Community

Tweenlite regression (using scrollTo)

massic80 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

Hi all!

I set up a site using TweenMax 1.9.5 for any animation, and everything worked properly.

Later, I updated the libraries to 1.9.7 and finally to 1.9.8.

With current version, the animations don't work properly; there is a conflict with Addthis dynamically created iframes.

Here is a sample code reproducing the problem with a YouTube static iframe:

<!DOCTYPE html>
<html>
<head>
    <!-- 1.9.6 --> <!-- <script type="text/javascript" src="https://raw.github.com/greensock/GreenSock-JS/f91853a0e9f753c1ae8b6b36172a4d42759296af/src/uncompressed/TweenMax.js"></script>-->
    <!-- 1.9.7 --> <!-- <script type="text/javascript" src="https://raw.github.com/greensock/GreenSock-JS/7c36c8f249526f687e185caa599a6e39bbed15e9/src/uncompressed/TweenMax.js"></script> -->
    <script type="text/javascript" src="https://raw.github.com/greensock/GreenSock-JS/ab62042130fa8f6a875b92bd2532d1f39d7a18f4/src/uncompressed/TweenMax.js"></script>
    <!-- Still the same from february --> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.9.8/plugins/ScrollToPlugin.min.js"></script>

    <style type="text/css">
        body > div {
            background-color:green;
            height:5000px;
        }
    </style>
</head>
<body>
    <div></div>
    <iframe width="560" height="315" src="http://www.youtube.com/embed/CZF2o06mlgQ" frameborder="0" allowfullscreen></iframe>
    <script type="text/javascript">
    setTimeout(function(){ // This is to allow the iframe being loaded
        TweenMax.to(window, 2,
            {
                scrollTo:
                {
                    y: 2500, autoKill:false
                },
                onComplete: function()
                    {
                        alert("end");
                    }
            });
    },10000);
    </script>
</body>
</html>

As you can see, an error is thrown in TweenMax.js, line 5700. In that location, "target" is "window" when attempting to scroll it, but window[0] (target[0]) doesn't allow the access to "nodeType" property.

In particular, Firefox says "Error: Permission denied to access property 'nodeType'" and Chrome indicates a cross-domain conflict between the current page and the imported in the iframe one.

I figure out that this happens because window object also contains the included frames and iframes (http://www.w3schools.com/jsref/obj_window.asp), hence target[0] isn't the "desided" window object, but only the first contained iframe. There should be a window.frames[x], but looks like that window[x] works in the same way (as well as window.length), that is an array of window objects (cross domain or not).

Reverting to TweenMax version 1.9.5 (the last working I had on SVN), everything works as expected.

 

In the reported example I also included the commented imports of previous versions, and the last which looks like working is 1.9.6.

Moreover, another animation in my pages throws a similar error on native IE8, and looks like 1.9.5 doesn't do the same: I didn't investigate deeply in this, because maybe that fixing the regression will also fix the other trouble. I'll get some time to do it if U wished :)
Thanks in advance for your precious help

Massi

Link to comment
Share on other sites

Hi,

 

This is an odd behaviour.

 

I've changed the script source from the git repository to the minified copy in CDNJS and it worked fine, although It keep throwing an error and strange behaviour in IE (what a surprise  ^_^); while firebug and dev tools throw an error with the embedding code of the video, IE gives the error  on line 5700 of TweenMax.js. So I commented out the iframe from the html code and works fine all the way back to IE7.

 

Basically we're talking about a problem due to interaction between youtube's embedding code and TweenMax.js. Now why is this happening?, I have no idea. One option is that you could try the <embed> method instead of the iframe, but this has to do with the scripts interacting.

 

Hope this helps,

Cheers,

Rodrigo.

Link to comment
Share on other sites

Thanks a lot, Rodrigo.

In fact, I don't care about YT code error, it's just a side effect from the example I chose :)

I think that "odd" is a good definition for this weird problem: it becomes even more weird, because you just said that switching to minified version you didn't detect any error: I started from the minifed version (of course) and chose to use the uncompressed one on the example for a better view on the trouble origin (In the minified version, the error occurs on line 16). Did you leave the ten second timeout pass? :)

 

Oh, right, what a surprise, having a problem on IE! Let's go on on Firefox and Chrome, anyway ;)

 

The embed maybe a temporary solution, but since the trouble DOESN'T occur with former versions of TweenMax, the problem is just in the two latest releases, and I can't workaround a library trouble (I'd stop using it if I had to): it should be solved where it comes from.

Anyhow, I couldn't work on the iframes because they are dynamically created by Addthis: yes, the markup inserted by them isn't great coding, but since 1) they are on lots of sites 2) TweenMax 1.9.6 worked 3) TweenMax should be able to work on all the sites, including those with iframes (YT, for instance), I think that something new (or old?) should be implemented:
I'll give you all the support I'm able to. ;)
Do you agree?

Thanks again and "see you" soon

Massi

Link to comment
Share on other sites

Hi,

 

Well the problem seems to happen only with IE and when using the scrollTo plugin, using the following code:

<script type="text/javascript" src="js/gsap/TweenMax.js"></script>
    <!-- Still the same from february --> <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.9.8/plugins/ScrollToPlugin.min.js"></script>

    <style type="text/css">
        body > div {
            background-color:green;
            height:5000px;
        }
		#div1{
			height:100px;
			width:100px;
			background:#00f;
			position:fixed;
			top:10px;
			left:10px;
		}
    </style>
</head>
<body>
    <div></div>
    <div id="div1"></div>
    <iframe width="560" height="315" src="http://www.youtube.com/embed/CZF2o06mlgQ" frameborder="0" allowfullscreen></iframe>
    <script type="text/javascript">
	var div1 = document.getElementById('div1');
	var win = window;
	
	TweenMax.to(div1, 2, {left:300, top:300, delay:3});
	
    //TweenMax.to(win, 2,{scrollTo:{y:2500, autoKill:false}, onComplete:function(){ console.log("end"); } /**/, delay:3});
	
    </script>
</body>

The blue square (div1) tweens to the indicated position and there's no error. If you uncomment the scrollTo tween it works in firefox, chrome, opera and safari, but you get an error pointing to youtube's embedding code. In IE, on the other hand, the div1 tween works fine but there's a jump to the scroll position, ie, no scroll animation and you get the error to line 5700 character 5.

 

Unfortunately this is beyond my abilities and I won't be able to solve this.

 

Cheers,

Rodrigo.

Link to comment
Share on other sites

Hi Rodrigo,

thanks for the answer and the solution, but I think that we have found a bug in the new solution ideated to differentiate if the first argument is a selector or an js object.

Therefore the problem presents itself if you pass "window" as argument to a tweenlite declaration and there are some iframes in the page.

 

This is the functioning line of code (until v 1.9.6):

var isSelector = (target.jquery || (typeof(target.each) === "function" && target[0] && target[0].nodeType && target[0].style)),

This is the incriminated line of code (starting from v 1.9.7):

var isSelector = (target.jquery || (target.length && target[0] && target[0].nodeType && target[0].style && !target.nodeType)),

Here if you pass window as target to the TweenLite function and there are iframe you get that:

1) target[0] is the first iframe of the page and not the top window

2) its impossible to get nodeType property for cross domain issue

 

One ease and rough solution is:

var isSelector = target == window ? false : (target.jquery || (target.length && target[0] && target[0].nodeType && target[0].style && !target.nodeType)),

So the problem is in the new solution adopted to detect the object involved in the animation.

 

Thank you

Link to comment
Share on other sites

Hi to all,

I forget to post a simple test

Code until v1.9.6

function test(target)
{
var isSelector = (target.jquery || (typeof(target.each) === "function" && target[0] && target[0].nodeType && target[0].style));
return isSelector;
}
test(window);

Code from v1.9.7

function test(target)
{
    var isSelector = (target.jquery || (target.length && target[0] && target[0].nodeType && target[0].style && !target.nodeType));
    return isSelector;
}
test(window);

If you test these two different function in the console in this same page (that have 6 iframes in it) you can view the issue.

Of course you can also test the functions with the example above, because youtube has nothing to do with the bug

 

Best Regards

Jacopo

  • Like 1
Link to comment
Share on other sites

Thanks anyway, Rodrigo :)

I thought you were the developer who submitted the latest changes ;)

Let's stay tuned on this topic, anyway.

Massi

Hi Massi,

 

The Greensock developers and forums staff is composed by Carl Schooff and Jack Doyle, I'm just a GSAP enthusiast  :mrgreen:.

 

Anyway glad Jacopo was able to fix this.

 

Cheers,

Rodrigo.

Link to comment
Share on other sites

Aha, this looks like an iframe issue (which might be able to be resolved by changing the header on the server-side, as described at http://davidwalsh.name/iframe-permission-denied) but we'll look into adding some code to the conditional statement to work around this too. The problem with the old code that looked for "each" is that it wouldn't work for things like Angular's jqLite. Would you try this?: 

var isSelector = (target.jquery || (target.length && target[0] && (target[0] === window || target[0].nodeType) && target[0].style && !target.nodeType))

?

Link to comment
Share on other sites

Right, the goal of the logic is to determine if it's a selector (like jQuery or Zepto or Sizzle or jqLite, etc.) so it would correctly return false when you pass "window" as the target, and it would still return "true" if you selected window through a selector, like $(window). Right? Or did I misunderstand something? (sorry, I haven't had time yet this morning to run tests - I just wanted to run the logic past you). 

Link to comment
Share on other sites

  • 4 weeks later...

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