Jump to content
Search Community

error cannot assign to read only property of '_gsTweenID'

Sahil test
Moderator Tag

Go to solution Solved by Sahil,

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 am using GSAP in a CMS site which loads a lot of javascripts on certain pages, and two of such pages throws following error from TweenMax library,
 

 

Uncaught TypeError: Cannot assign to read only property '_gsTweenID' of .

 

 

I can list all the libraries it is loading if necesarry. This certain error only happens if I launch animations on document.ready event but if I use timer(which is how I am going to use it in future) then this error don't occur, still I would like to know what might be causing this to happen.

 

EDIT: This error doesn't occur in firefox.

 

Also I would like to know if jquery plugin is being dropped in future as its documentation is removed?

Link to comment
Share on other sites

That usually means you are trying to tween something that can't be referenced, like a variable. Make sure what you are trying to tween is an object. Here's an example of that error.

 

See the Pen 4573cb383fc103702c0ce4d8fc999955 by osublake (@osublake) on CodePen

 

I'm not sure why the jQuery docs aren't with the other ones, but it's still active.

http://greensock.com/jquery-gsap-plugin

  • Like 4
Link to comment
Share on other sites

So adding delay works for me now as that's what I was going to do with tween anyway but is there any other way I can make sure this problem doesn't occur?

The same code works on all other pages and Firefox only chrome, IE(doesn't fire the tween but rest of animations work), Opera has the problem with two pages.

Link to comment
Share on other sites

Can you give an example of this? And what type of things are you trying to animate?

 

It sounds like if it works with a delay, then the object you are trying to tween might not be ready yet. How long of a delay are you using? Is it just one cycle, like 1ms? If so, my best guess would be that the object is created async. This could be related to your CMS. What CMS and other libraries are you using?

  • Like 2
Link to comment
Share on other sites

Regarding, jquery.gsap.js the reason it isn't in the docs is mostly because it isn't really part of the API. It is just a file that automatically offloads jQuery animate() calls to GSAP. It isn't a typical JavaScript class with methods or properties. 

 

jquery.gsap.js was created mainly to illustrate how much of a speed increase GSAP could give "out of the box" over jQuery. We have no plans to drop support for this jquery.gsap.js but at this point in GSAP's lifespan we're hoping that its pretty clear that using the GSAP API is a much better option than doing anything at all with jQuery.animate(). 

  • Like 2
Link to comment
Share on other sites

@OSUblake Sorry it doesn't work with delay either. I am using Joomla and I can confirm the Mootools library is causing problems though I have jquery in noConflict mode. I was done with layout but wanted to migrate all my animations(nothing complex) to GSAP.

 

I have two tweens right now. One for hover event which works fine when using delay and other one fires on document.ready, which throws the error and except on firefox other tweens stop responding. But with delay other animations work, without delay javascript stops altogether.

 

@Carl Yes, not seeing plugin made me migrate completely to GSAP.

Link to comment
Share on other sites

jQuery is fine still I tried wrapping it just to make sure and behavior didn't change. I spent some time as any tween on those pages wasn't working except hover event, which I was calling tweening elements using 'this'. So with mootools, GSAP has problem while tweening multiple elements. Following is codepen with two divs, first works as it tweens using 'this' reference and second tween doesn't work when tweening multiple elements.

 

See the Pen LpYvaQ by Sahil89 (@Sahil89) on CodePen

Link to comment
Share on other sites

That's same as using "this" in jQuery, and no, I don't even use mootools. Joomla documentation says they dropped it almost two years ago but still they have it in their contact form and some third party gallery plugin I am using.

 

So main problem is I can't tween two elements at once though for now I can disable mootools in current project, it will be great if I find permanent solution to get both libraries co-exist as a lot of joomla extensions still use mootools.

Link to comment
Share on other sites

hi OSUblake thanks for your support so far, following is codpen where events are implemented using jQuery. On clicking second div both divs move to right. With mootools I can tween single element at once but while tweening two elements like in this codepen, it causes problems.

 

See the Pen RWwmoO?editors=101 by Sahil89 (@Sahil89) on CodePen

 

I guess I should get on MooTools forum to find any solution or maybe Carl must know how to get rid of this problem.

Link to comment
Share on other sites

To add to Blakes great advice..

 

if you dont want to use jQuery.noConflict() then in Joomla you can just use jQuery instead of the factory symbol ($). I presume you are using a version of Joomla above 3.x where jQuery has replaced MooTools. If MooTools is being used in a plugin.. it could take ownership of the factory symbol ($), if it is loaded after jQuery.

 

Also sometimes when working in Joomla, its best to use the Joomla API for adding javscript. Since Joomla gets a little wonky when adding custom javascript

 

https://docs.joomla.org/Adding_JavaScript

 

I hope this helps! :)

  • Like 3
Link to comment
Share on other sites

I was using jQuery in noConflict mode anyway but still it doesn't work for me. For now I have disabled MooTools, I will update this thread when I find solution.

 

EDIT: @Jonathan Yes I followed recommended methods while adding scripts and used jQuery without $ sign, and even wrapped it the way OSUblake suggested to make sure, but so far problem persists.

Link to comment
Share on other sites

Finally I have found the problem and solution. I was using a plugin called eorisis: jQuery to manage all scripts and styles.

 

1. I disabled MooTools and everything worked fine.

2. I re-enabled MooTools and disabled plugin, thinking maybe itself might be causing problem but problem remained.

3. Finally in this plugin there is option to enable/disable noConflict mode and after disabling it all three libraries worked fine together.

 

Both Joomla and this plugin adds single line file to remove jQuery conflict and files load in following sequence

1. jQuery

2. noConflict file

3. mootools

 

So now as long as all extensions I use follow recommended methods while using jQuery I wont have any conflicts, right? And to be honest I don't yet completely understand this issue as how come defining noConflict before MooTools is affecting GSAP?

Link to comment
Share on other sites

To play it safe you could do as Blake recommended above and call jQuery.noConflict() before your custom code again since mootools was run after jQuery.noConflict().

 

Like i advised above.. if you dont want to use jQuery.noConflict just use jQuery instead of the factory symbol ($)

jQuery.noConflict();

jQuery(document).ready(function(){
 
  jQuery('#one').click(function(event){
      console.log("one", event);
    TweenMax.to(this, 1, {left: "+=100"});
  });

  jQuery('#two').click(function(event){
      console.log("two", event);
    TweenMax.to("div", 1, {left: "+=100"});
  });  

});

Also the best way to make sure your custom jQuery code will run is just make sure your custom javascript file is the last one loaded in joomla. So just hardcode your script tag in your joomla footer before the body.

 

Or you can use jQuery.noConflict() as an alias

var $j = jQuery.noConflict();
 
$j(document).ready(function(){
 
  $j('#one').click(function(event){
      console.log("one", event);
      TweenMax.to(this, 1, {left: "+=100"});
  });

  $j('#two').click(function(event){
      console.log("two", event);
      TweenMax.to("div", 1, {left: "+=100"});
  });  

});

Also i don't believe the jQuery.noConflict is affecting GSAP, but your jQuery event handlers that are using the factory symbol

 

But your issue does not seem like a GSAP issue, but more on how your mixing javascript libraries in Joomla.

 

But like i advised above your best bet is to make sure your custom javascript file is the last script loaded, and just use jQuery  reference name instead of the factory symbol ($)

 

:)

  • Like 1
Link to comment
Share on other sites

Yes from very start I never used $ symbol and out of all the different ways I tried to get to the root of the problem, only disabling noConflict in plugin which stops that single line file from loading worked for me, which makes me believe is the problem.
 
And while I was typing I tested it locally as I am not sure if I can edit codepen this way, here is code that confirms noConflict before MooTools affects GSAP.

<!DOCTYPE html>

<html>
<head>
    <title>GSAP n Mootools</title>    
    <style>
        div{
            display: block;
            position: relative;
            height: 100px;
            width: 100px;
            background-color: #234455;
            margin: 10px;
        }
    </style>    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script>jQuery.noConflict();</script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.5.1/mootools-core-full-compat.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>    
    <script>
        jQuery.noConflict();
        (function($){
        
            $(function(){
                
                $("#one").click(function(){
                    TweenMax.to(this, 1, {left: "+=100"});    
                });
            
                $("#two").click(function(){
                    TweenMax.staggerTo("div", 1, {left: "+=100"}, 0.2);    
                });
                
            });                        
        })(jQuery);
    </script>
</head>

<body>
<div id="one">
    
</div>
<div id="two">
    
</div>
<div id="three" >
    
</div>
</body>
</html>
Link to comment
Share on other sites

What your seeing is that MooTools is affecting jQuery not GSAP. GSAP is not dependent on jQuery! ;)

 

Your above code is using jQuery event handlers which are being affected by the inclusion of MooTools. That is more of a joomla issue, that is why i advised to use Joomla API to include your custom javascript. I use Joomla all the time, much to my dissatisfaction.

 

And the way i get around adding custom code in Joomla is to either add my custom javascript and/or javascript libraries using the Joomla API. Or add GSAP and your custom script to the bottom of the footer, right before the ending body tag.

 

But again the inclusion of jQuery.noConflict is affecting jQuery not GSAP! Since your GSAP code is inside the jQuery event handlers,  it doesn't run, due to the joomla mootools and jquery conflicts. I would check with the Joomla plugin developer about their extension and the inclusion of MooTools in your Joomla install.

 

But again your issue is more of Joomla javascript library conflict between MooTools and jQuery. GSAP has nothing to do with the two conflicting, which is causing your console error. So once you sort out your Joomla, MooTools, and jQuery conflicts than GSAP should run fine.

 

GSAP is not dependent on jQuery :)

Link to comment
Share on other sites

I am sorry but I have made it clear in few previous replies that I follow recommended methods to add script. And you must have noticed that problem only occurs when there are multiple elements involved. Now this is the edited code which shows that the problem is with GSAP's DOM selector when using with MooTools. You can also take a look at very first codepen in this thread which shows GSAP with MooTools works fine while using "this" to animate but it fails to animate when used div to select elements.

<!DOCTYPE html>

<html>
<head>
    <title>GSAP n Mootools</title>    
    <style>
        div{
            display: block;
            position: relative;
            height: 100px;
            width: 100px;
            background-color: #234455;
            margin: 10px;
        }
    </style>    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script>jQuery.noConflict();</script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.5.1/mootools-core-full-compat.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js"></script>    
    <script>
        jQuery.noConflict();
        (function($){
        
            $(function(){
                
                $("#one").click(function(){
                    TweenMax.to($("#one"), 1, {left: "+=100"});    
                });
            
                $("#two").click(function(){
                    TweenMax.staggerTo($("div"), 1, {left: "+=100"}, 0.2);
                });
                
            });                        
        })(jQuery);        
    </script>
</head>

<body>
<div id="one">
    
</div>
<div id="two">
    
</div>
<div id="three" >
    
</div>
</body>
</html>

In above code I have used jQuery selectors which shows jQuery isn't affected at all but GSAP DOM selector gets affected instead. This code and very first codepen shows that GSAP DOM selector fails.

Link to comment
Share on other sites

You do not need to use MooTools selector engine.. MooTools is your issue in Joomla with the ownership of the factory symbol. GSAP has nothing to do with this conflict! :D  Just simply add your selector inside the target parameter for your to() method, as a string within the quotes.

 

GSAP doesn't need MooTools to query the DOM, just omit your MooTools wrapper $(). It is much better and faster to just place your CSS selector within the GSAP target parameter. It is already built inside GSAP using native javascript methods, document.querySelectorAll(), which is faster than using the jQuery or MooTools selector engine collection wrapper.

$("#one").click(function(){
      // GSAP does need the MooTools collection wrapper $()
      TweenMax.to("#one", 1, {left: "+=100"});    
});
            
$("#two").click(function(){
      // GSAP does need the MooTools collection wrapper $()
      TweenMax.staggerTo("div", 1, {left: "+=100"}, 0.2);
});

The to() method has a target object

TweenMax.to( target:Object, duration:Number, vars:Object ) : TweenMax

[static] Static method for creating a TweenMax instance that animates to the 
specified destination values (from the current values).

target : Object

Target object (or array of objects) whose properties should be affected. When animating DOM elements, the target can be: a single element, an array of elements, a jQuery object (or similar), or a CSS selector string like “#feature” or “h2.author”. GSAP will pass selector strings to a selector engine like jQuery or Sizzle (if one is detected or defined through TweenLite.selector), falling back to document.querySelectorAll().

 

Resources:

TweenMax: http://greensock.com/docs/#/HTML5/GSAP/TweenMax/

to(): http://greensock.com/docs/#/HTML5/GSAP/TweenMax/to/

 

It is always best to go the path of least resistance, especially with Joomla :rolleyes:

 

I hope this helps :)

Link to comment
Share on other sites

  • Solution

I never used MooTools selectors, problem is with GSAP selectors while using it with MooTools. To prove my point check my last code where I use jQuery selector and code works fine, removed $() to get rid of jQuery selectors and GSAP fails(in presence of MooTools). Remove jQuery to use GSAP with MooTools only and GSAP selectors will fail(take a look at my first codepen).

 

I don't know if MooTools is doing it wrong or GSAP, neither is problem of Joomla because above code is single HTML file with similar behavior. My knowledge isn't that deep but I guess when we declare noConflict before MooTools, it takes control of more than just $ sign and affects GSAP in the process. GSAP developers should look into it.

 

Finally if anybody comes to this thread with same problem, I will recommend to use jQuery selectors. Thank you.

Link to comment
Share on other sites

Here are a few things that seem to be of note.

 

TweenLite automatically searches for $ and if it finds something it uses that as the internal selector engine.

99.99% of the time $ is jQuery or Sizzle. 

 

In MooTools land $ is only a shortcut for document.getElementByID

 

http://mootools.net/core/docs/1.5.1/Element/Element#Window:dollar

The dollar function is an alias for document:id if the $ variable is not set already. However it is not recommended to use more frameworks, the $ variable can be set by another framework or script. MooTools will detect this and determine if it will set the $ function so it will not be overwritten.

 

To support more robust CSS selectors, MooTools has $$

http://mootools.net/core/docs/1.5.1/Element/Element#Window:dollars

Selects and extends DOM elements. Return an Elements instance. The Element instance returned is an array-like object, supporting every Array method and every Element method.

 

So the issue is most likely that TweenLite finds MooTools' $ and passes selector strings off to that.

Its failing because $ only supports ID.

 

So you have 3 options for now

//use $$
TweenLite.to($$("div"), 1, {x:100});
//use jQuery
TweenLite.to(jQuery("div"), 1, {x:100});

//or load jQuery and tell TweenLite to use it as its selector like

TweenLite.selector = jQuery;
TweenLite.to("div"), 1, {x:100}); 

Here is a pen with some helpful logs:

 

console.log("single $ " + $("div")) // This should not, and does not work
console.log("double $$ " + $$("div")) //this does work
$$("div").each(function(){
  console.log("a div")
})


var callone = function(event){
  TweenMax.to(this, 1, {left: "+=100"});
};
        
var calltwo = function(event){
  var t =  TweenMax.to($$("div"), 1, {left: 100});
  console.log(t.target)
 };
        
document.id("one").addEvent('click', callone);
document.id("two").addEvent('click', calltwo);  

 

http://codepen.io/GreenSock/pen/qOEaMX?editors=001

 

I have to study a little further to see why setting the selector to $$ is not working.

TweenLite.selector = $$
  • Like 4
Link to comment
Share on other sites

 

So the issue is most likely that TweenLite finds MooTools' $ and passes selector strings off to that.

Its failing because $ only supports ID.

 

Right, passing id without # works on id in the presence of MooTools. Well conflicts are frustrating but less than seeing GSAP animations when I didn't know about GSAP and I kept saying to myself I know nothing about animations. Until I found out how those smooth animations were done. Thanks, great library!

Link to comment
Share on other sites

I believe I found the problem - MooTools relies on a particular scope in the call. So for example:

var obj = {},
    obj.selector = $$;
console.log(obj.selector("div"), " vs ", $$("div")); //different results!

Notice they're both referencing exactly the same function but they return different results. 

 

Here's a solution:

TweenLite.selector = function(t) {
    return $$(t);
};

Just do that first and it should resolve all the issues with MooTools (as far as I can tell at least). 

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