joe_midi

Polite loading GSAP into a DC HTML5 banner

Recommended Posts

I was wondering how do you detect that GSAP is loaded into the DOM and ready to animate the banner?

 

DoubleClick provides you with this in their example of polite loading a banner, where the JS and CSS is loaded later into the DOM.

<script src="http://s0.2mdn.net/ads/studio/Enabler.js" type="text/javascript"></script>	
<script language="javascript">
	//Initialize Enabler
	if (Enabler.isInitialized()) {
		init();
	} else {
		Enabler.addEventListener(studio.events.StudioEvent.INIT, init);
	}
	//Run when Enabler is ready
	function init(){
		if(Enabler.isPageLoaded()){
			politeInit();
		}else{
			Enabler.addEventListener(studio.events.StudioEvent.PAGE_LOADED, politeInit);
		} 
	}

	function politeInit(){		
	//Load in Javascript
	var extJavascript = document.createElement('script');
	extJavascript.setAttribute('type', 'text/javascript');
	extJavascript.setAttribute('src', Enabler.getFilename('DCRM_HTML5_inPage_Polite_300x250.js')); 
	document.getElementsByTagName('head')[0].appendChild(extJavascript);

	//Load in CSS
	var extCSS=document.createElement('link');
	extCSS.setAttribute("rel", "stylesheet");
	extCSS.setAttribute("type", "text/css");
	extCSS.setAttribute("href", Enabler.getFilename("DCRM_HTML5_inPage_Polite_300x250.css")); 
	document.getElementsByTagName("head")[0].appendChild(extCSS);
	document.getElementById("container_dc").style.opacity=1;
	document.getElementById("loading_image_dc").style.opacity=0;
	document.getElementById("container_dc").style.display = "block";
}
</script>
But I found that when I added GSAP to this, my code would always load first then fire off and not wait for GSAP to be ready.
So a dug a little deeper into DC's Enabler.js and found they actually had a loadScript function with call back.
 
<script src="http://s0.2mdn.net/ads/studio/Enabler.js" type="text/javascript"></script>	
<script language="javascript">
	var TweenLiteJS = false, CSSPluginJS = false, EasePackJS = false;
	//Initialize Enabler
	if (Enabler.isInitialized()) {
		init();
	} else {
		Enabler.addEventListener(studio.events.StudioEvent.INIT, init);
	}
	//Run when Enabler is ready
	function init(){
		if(Enabler.isPageLoaded()){
			politeInit();
		}else{
			Enabler.addEventListener(studio.events.StudioEvent.PAGE_LOADED, politeInit);
		} 
	}

	function politeInit(){
	Enabler.loadScript('//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenLite.min.js', function(){console.log("TweenLite Loaded"); TweenLiteJS = true;});
	Enabler.loadScript('//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/CSSPlugin.min.js', function(){console.log("CSSPlugin Loaded"); CSSPluginJS = true;});
	Enabler.loadScript('//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/easing/EasePack.min.js', function(){console.log("EasePack Loaded"); EasePackJS = true;});
	Enabler.loadScript('script.js', function(){console.log("BannerScript Loaded"); Banner.init();});

	//Load in CSS
	var extCSS=document.createElement('link');
	extCSS.setAttribute("rel", "stylesheet");
	extCSS.setAttribute("type", "text/css");
	extCSS.setAttribute("href", Enabler.getUrl("styles.css")); 
	document.getElementsByTagName("head")[0].appendChild(extCSS);
	document.getElementById("banner").style.opacity=1;
	document.getElementById("loading").style.opacity=0;
	document.getElementById("loading").style.display = "none";
	document.getElementById("banner").style.display = "block";
	}
</script>

So I ended up with this in the HTML and then this in the JS

Banner.init = function(){
	//Just an extra check to make sure all library files have loaded as well.
	if (document.readyState === "complete") {
		if( !TweenLiteJS  || !CSSPluginJS  || !EasePackJS) {
			console.log("Not ready to animate yet, try again in 500ms");
			setTimeout( Banner.init, 500 );
		} else {
			console.log("Animation start");
			Banner.animate();
			addListeners();
	    }
	}
}

And it works, the animation isn't fired off before its ready to. I was just wondering if I've over complicated things, or I've missed something. I actually got this idea from @letssock when talking about implementing GSAP into Celtra.

  • Like 3

Share this post


Link to post
Share on other sites

I'm not that familiar with Enabler, but I'd probably just whip together my own politeLoad() function that I can feed an array of scripts to and then have it call a function when they're all done, like this:

 

function politeLoad(urls, onComplete) {
    var l = urls.length,
        loaded = 0,
        checkProgress = function() {
            if (++loaded === l && onComplete) {
                onComplete();
            }
        },
        i;
    for (i = 0; i < l; i++) {
        Enabler.loadScript(urls[i], checkProgress);
    }
}
//now you can just feed stuff into that one function and give it a callback...
politeLoad(['//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenLite.min.js',
            '//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/plugins/CSSPlugin.min.js',
            '//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/easing/EasePack.min.js',
            'script.js'], function() {
    Banner.init(); //or whatever you want called
});

That way, you can avoid the setTimout() stuff and ensure that things happen the moment everything loads.

 

Does that help? 

  • Like 4

Share this post


Link to post
Share on other sites

Joe, thanks for posting your solution and question regarding the polite load.

From looking at DC's Enabler documentation, how you do the polite load or determine when its done is certainly a bit of a mystery.

Very cool that you shared your findings here, I think with Jack's addition we all have a solid starting point now.

Share this post


Link to post
Share on other sites

Thank you Jack & Carl.

 

That is totally a sweet solution.

 

I'm very keen on sharing any insight on banner production here whenever I'm able to, it helps me think things through, and will surely help others.

  • Like 1

Share this post


Link to post
Share on other sites

Hey There Gents,

 

I was on Doubleclick "chat" ( a really great resource for Doubleclick support BTW)  for quite some time with this issue. Their Templates are a bit dated. This is the solution we came up with and it works like a charm. This Script goes in the <head> tag.

 

 

 
<script language="javascript">
 
//Initialize Enabler
if (Enabler.isInitialized()) {
 
init();
 
} else {
 
Enabler.addEventListener(studio.events.StudioEvent.INIT, init);
}
 
//Run when Enabler is ready
function init(){
 
if(Enabler.isPageLoaded()){
 
politeInit();
 
}else{
 
Enabler.addEventListener(studio.events.StudioEvent.PAGE_LOADED, politeInit);
}
 
function politeInit(){
 
Enabler.loadScript('TweenLite.min.js', load1);
}
     
            // To make sure that all the js animation files will be fully loaded
            // before using them, use the loadScript method which has a callback function
     
            function load1(){
                Enabler.loadScript('zepto.js', load2);
            }
            function load2(){
                Enabler.loadScript('EasePack.min.js', load3);
            }
            function load3(){
                Enabler.loadScript('CSSPlugin.min.js', load4);
            }                        
            function load4(){
                Enabler.loadScript('connectionsPolite.js');
            }
</script>

Share this post


Link to post
Share on other sites

Pretty good solution actually and makes sense, just chain them up in order of dependencies.

 

But, and correct me if I'm wrong on this, you'll end up waiting longer as the user would need to wait for the first script to download before downloading the next, so that all the scripts are actually downloaded in a series; one after another, instead of grabbing them as soon as possible, which is a more normal web-development practice.

 

(Although, having a banner wait longer before it renders isn't necessarily a bad thing, after all its not mission critical to the website, just the advertiser.)

Share this post


Link to post
Share on other sites

Yep, I agree with Joe - rather than queueing them up and loading them one-by-one, it'd be better/faster to load them concurrently if at all possible. I also think the one-by-one technique will require more manual code as you add more scripts which is why I tried to encapsulate things into that one politeLoad() function that does all the work for you no matter how many scripts you pass in through the array. See what I mean? 

 

Did you run that method past DC? Was there a particular reason they advised you to do the sequential load, adding a new function for each? Just curious. 

Share this post


Link to post
Share on other sites

Thanks Jack

 

Where would you put the GSAP polite loader? Before or after the Doubleclick enabler one?

//Initialize Enabler
		if (Enabler.isInitialized()) {
			init();
		} else {
			Enabler.addEventListener(studio.events.StudioEvent.INIT, init);
		}
		//Run when Enabler is ready
		function init(){
			//politeInit();
			//Load in Javascript
			
			if(Enabler.isPageLoaded()){
				politeInit();
			}else{
				Enabler.addEventListener(studio.events.StudioEvent.PAGE_LOADED, politeInit);
			} 
		}
		
		function politeInit(){		
			//Load in Javascript
			var extJavascript = document.createElement('script');
			extJavascript.setAttribute('type', 'text/javascript');
			extJavascript.setAttribute('src', Enabler.getFilename('DCRM_HTML5_inPage_Polite_300x250.js')); 
			document.getElementsByTagName('head')[0].appendChild(extJavascript);

Share this post


Link to post
Share on other sites

Well, the code I wrote assumes that the Enabler exists on the page. So yeah, probably after. But for things like this that are specific to DoubleClick and their proprietary Enabler, it's probably best to ask them. We try to keep these forums focused on GreenSock-specific questions. Please let us know if it works okay for you or if you get different advice from DoubleClick. 

 

Happy tweening!

Share this post


Link to post
Share on other sites

Thanks. That is what I was thinking too. I just did not have an example at the ready to try it on and I am not a javascript guru..

 

I do think this "oh ****" moment in the Flash ad building world is a great opportunity for GSAP to grab market share.

Share this post


Link to post
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.