Post Page-Loading iPad/iPhone/iPod CSS Styles, But Only When Needed

March 29, 2012

(For the purposes of this article I will only refer to the iPad, however, I am speaking in terms of any i-Product: the iPad, the iPhone, or touch iPod.)

Recently, I designed a large website that needed to work on all the basic desktop browsers (IE 7/8/9, Safari, Firefox, Chrome). Everything went great until I was done with the site. As soon as I was done, I was told that it now needed to support the iPad. This was not a big deal but was a little problematic since I had not initially designed the site for viewing on those devices. However, the site was all standard CSS, HTML, and JavaScript so I knew it would not be a major task to add in support.

The Problem with iPad
Right away, I ran into a few problems. The first problem was the fact that the iPad relies on the onclick() method being attached to an element in order to determine if it should pass synthesized mouse events to it or not. I solved this with a pretty simple method, and I have written an article that explains my solution in-depth, here. For now, the subject of this article deals only with the iPad’s default CSS settings. Mainly, the fact that scrollbars are turned OFF by default on these devices and how to easily turn them back on, but only when the user is viewing your site with an iPad. “Aha!”, you say… why can’t we just add these CSS changes to our main site’s CSS definitions? Because Safari on the desktop and iPad use the same Webkit CSS package. Which means that if you want to customize your CSS look for each of these versions of Safari, you will need to determine on-the-fly which device is looking at your site and make any CSS additions needed (or not). Also, because of future updates to other browsers, we want to make sure that we do not inadvertently affect these other browsers by assigning styles we do not need.

You see, when the iPad user interface was designed, it was decided that scroll bars were a thing of the past and should be turned OFF by default. Touch commands are the new darling of the user interface community, but since not every device is touch-event driven, this can cause problems for web designers. Ideally, you want to have as few versions of a website as possible. Ideally, you strive for a single, perfect website. One that looks great on all devices. But realistically, this never happens since a website that looks awesome on one device rarely looks good enough on all the others… so, for now, you usually end up creating two websites – one for desktops/tablets, and one for mobile phones.

Bye-Bye Scrollbars
Now, a lack of scrollbars is normally not a problem on the iPad, especially for sites designed specifically for viewing on these devices. But there have been many times I have designed sites which contain smaller, scrollable regions on their pages which do not visually look scrollable when viewed on an iProduct. Since our overall goal as great designers is to always strive for creating intuitive content, this lack of scrollbars can actually work against us by bringing down our site’s overall initial intuitiveness and usability.

Maybe scrollbars are a thing of the past, but for now, users will still need them in order to help them make the move across the gap from traditional to touch-based user interfaces. Sure, most iPad users are aware that you can drag elements and they will scroll if they are able to scroll. But, what gets overlooked is that sometimes elements which DO contain scrollable content don’t look like they are scrollable, so users will not even try. They have no scrollbars acting as a visual cue to let users know they can scroll this item’s content, so a lot of visitors (who may be paralyzed by the fear of clicking the wrong thing) won’t explore your page and so miss important content. So, what to do? Well, add scroll-bars! But how do we do that for just the iPad?

What I needed was a solution that was not a plug-in, or some browser-based hack. It had to be robust. It couldn’t be brittle and break after the first update to any of the site’s supported browsers. You see, in these days of constant software updates, many browsers now update themselves without requiring the user to actively seek updates, download them, then install them manually.

This is great for keeping your browser current, but it also means that every time a browser is updated, any non-standard, remotely-fragile solutions that you have hacked together to make your site function, have now become time bombs. You never know which update to which browser will cause them to halt your site’s functioning. So, any web design solutions you implement need to be simple, based on standard web technologies, and robust without depending on a specific browser version to work properly.

Apple’s Webkit
Apple has a great web browser resource called the WebKit Open Resource Project which is:

WebKit is an open source web browser engine. WebKit is also the name of the Mac OS X system framework version of the engine that’s used by Safari, Dashboard, Mail, and many other OS X applications. WebKit’s HTML and JavaScript code began as a branch of the KHTML and KJS libraries from KDE…

It does a great job by default on most items. However, if your page really needs to have those small, indicating scrollbars, then you need to turn them on yourself using webkit without affecting the rendering of your page in other, desktop browsers, like Safari. If you are not careful, you will end up with tiny scrollbars in the desktop version of Safari as well as the iPad version. Why? Because they both rely on Webkit! So, if you don’t filter the userAgent to look for just the iPad info, then you inadvertently end up assigning the styles to both.

The Solution
So, how do you adapt your site to the iPad without requiring you to add a lot of extra code and style sheets to your website? Part of the answer is to use some JavaScript to do some post-load page manipulation in order to augment any elements that require special attention for them to function properly on the iPad (see my Article “Make Your jQuery Website Buttons/Links Work with iPad/iPhone”). The other half of the solution is to load some additional CSS styles, but only if the site is loaded onto an iPad.

You may be thinking right now,”Why not just use jQuery?”… well, the problem with that solution is that the additional CSS stylesheet really needs to be loaded in the HEAD tag of your HTML page, which means that this must be done BEFORE your jQuery even gets loaded. Also, if you try to simply re-write the page’s HEAD tag after load and after jQuery runs, you get unpredictable results in some browsers. So, the best solution is one that does not rely on any other API than the standard library of default JavaScript functions.

Below is the portion of the code where the magic happens. It is standard JavaScript and does not use jQuery since it has to happen in the head tag, before any jQuery is loaded and just after our site’s base CSS external definitions are loaded. To download the complete source and example files click here.

// we use a regular expression to see if the user agent string contains iProduct identifiers...
if( String(navigator.userAgent).search(/(ipad)|(iphone)|(ipod)/i) > 0 )
// we then dynamically add in an additional stylesheet definition.
// this must load AFTER your site's normal CSS definitions, or they might be overwritten
document.write('<link rel="stylesheet" type="text/css" href="scripts/website_styles_iproducts.css">');

To view the above code in action, load this page onto your iProduct then click here. You will not see any effect on any other non-iProduct browsers.

Last Note
You can use the above method to look for any particular browser or mobile device if you know it’s user agent identifier. Here is a good article to get you started on identifying other devices.

Just be sure that the over code appears INSIDE the head tag of your HTML page and AFTER the other link tags that you have loading your site’s main CSS definitions.


Successfully Searching Multidimensional Arrays in AS3

July 15, 2010

Please be aware that this tutorial is intended for intermediate-to-advanced ActionScript programmers and designers. It is therefore assumed that you have a competent understanding of the underlying principles and specifics of both versions of ActionScript. I cannot respond to all questions regarding this code. So, please assume that you are on your own. Notes, instructions, and any relevant documentation has been included in the FLA files. Also, you will need Flash CS3 or CS4 to read the source files included in this tutorial.

The Problem
There are times when you are creating something in Adobe’s Flash content creation suite, that you want to be able to have an array of arrays. These are called multidimensional arrays, and they are great for many purposes. Their only big drawback seems to be the lack of searchability in the entire array and sub-array elements.

Multidimensional arrays are like a large red box, with medium-sized blue boxes inside and even smaller yellow boxes in each medium-sized blue box. So, you have the parent array (the red box) and its individual elements (the blue boxes). Each blue box then contains its own array (the yellow boxes).

I Just Can’t Find Anything!
Normally, when you need to find an occurance of some string in another string, you use the handy “indexOf” method like this:

var myIndex:Number = sourceString.indexOf( "my search target" );

And it will generate either “-1” (not found) or an integer which is equal to the target string’s starting position in the source string.

Then try using the “indexOf” method on a regular array and you also get the results you expect. But try the same method a multidimensional array and things just fall apart. You get nothing but the dreaded “-1” result: the string you were looking for was not found anywhere in the array. Even if you search in each array element individually, you must still look for only EXACT matches (===). You cannot find partial matches like you can when searching a standard string.


  • myArray.indexOf( “find this” ) = FAILS!
  • myArray[ element0 ].indexOf( “find this” ) = FAILS!
  • myArray[ element0 ][ element0 ].indexOf( “find this” ) = FAILS! (returns the starting locating in the array element string, but not the array index!)

Let there Be Light.
Ooooooh! Pretty colors… I have finally come up with a SIMPLE, quick solution to finding strings in multidimensional arrays. I do it by using the “forEach” method on an array. It passes the array element, index, and entire array object to a function which can then pick through the contents to look for partial matches and return an array on the array object that contains ALL of its instances in the parent array. If you read the results array, it is a set of row and column indexes that can be used directly on your parent array to display the contents of the elements that contain your search target string. It all sounds a bit confusing, I know it took me a while to get my head around the problem, but once you read and run the code below, it will become really clear just how simple and useful this code can be.

And Now, the Code, Please…
Click here to download the CS4/CS3 FLA file. You may use this code as part of any project as long as you do not sell my code on its own or as part of any large, commercial project. This code is copyright 2010 Clarence “exoboy” Bowman, all rights reserved.

Also, Here is the Code For you Copy-Pasters
// set up a multidimensional array that contains some data
var myArray:Array = new Array();
myArray.push(["granola","people... are great"," 4 ","10"]);
myArray.push(["steve","gates","24","yes, sometimes"]);

// here we set up some properties on the array object to hold our search string and our results
myArray.myTarget = "ste";
myArray.myResults = [];

// now we call the search

// this is the function that does all the heavy lifting....
function multiSearch(element:*, index:int, array:Array)
// see if we have a match in this array and pass back its index
for(var i:* in element)
if( element[i].indexOf( array.myTarget ) > -1 )
var tempArray:Array = array.myResults;
array.myResults = tempArray;

// -------------------------------------------------------------------------------
// all the code below is OPTIONAL... it is just to show our results
// in the output window in Flash so you know it worked....
var printArray:Array = myArray.myResults;
for(var i:* in printArray)
trace("TARGET FOUND @: "+printArray[i][0]+", "+printArray[i][1]+" = "+myArray[ printArray[i][0] ][ printArray[i][1] ]);
// -------------------------------------------------------------------------------

Flexible, Dynamically-Expanding Columns with Absolute Positioning

April 22, 2010

April 22, 2010
To use this tutorial, you will need Prototype.js (v1.6) and a good working knowledge of javascript, CSS, and XHTML. This tutorial assumes you are an intermediate-to-advanced javascript programmer and understand the basics of programming and code design. I will keep the technical jargon to a minimum, but some concepts are just too basic to be covered in great detail here.
All of the files you will need are in this self-contained ZIP archive:
 Download this article’s source code here.


How many of you out there have wanted multiple columns of content on web pages without all of the required housekeeping drudgery to make sure all the content gets displayed properly and nothing gets clipped, overlaps or gets shoved around by other elements? And without the fear of getting a call from your client, telling you that the site does not look good in browser X? From the search results I came up with, it would seem that there are a LOT of others like me out there who are looking for a simple solution that does not required executing acres of processor-intensive code. If your page is torturously-slow, what good is pretty content?
It has been extremely frustrating finding something that is flexible with a minimum of customization and that works on all browsers. Of course, I am not talking about supporting legacy browser versions, like Internet Explorer 6 and older… that is a COMPLETELY different beast with razor teeth and slathering jaws waiting to clamp down on your unsuspecting ankles. So, for the purposes of clarity and simplicity, I am going to focus only on Safari 4 (mac) / 4 (pc), Opera 9 (mac) / 10 (pc), Chrome beta (mac) / 4 (pc), Firefox 3 (mac) / 3(pc), and Internet Explorer 7 (pc) / 8 (pc).
So, Why Bother? 
Good question! Couldn’t this be done using pure CSS? Theoretically it is possible to create a wrapper DIV, and then simply insert column DIV’s into the wrapper. Then, you would use the “display:inline-block” style to stack them left-to-right, or you could use the style “float:left” to take it out of the layout-stream. You could also assign the style “height:auto” to each column to have them automatically expand or contract the column DIV height. Well, theoretically, if you did not want any padding, or margins, or extra spacing around your columns this would seem like the obvious path to success… however, this is not an ideal world. Because of browser differences and flat-out incompatibilities, it will not work this easily. For example, if you used the float method, then because it is not a part of the document-flow, it will not adjust the height f the parent DIV that it is contained in: content will begin to spill out of the bottom of your wrapper DIV, ruining you nice, organized layout. As for the display method, it is lacking since the tops of the column DIV’s will tend to shift up or down depending on the height of its neighboring DIV… so many issues!
Trust me, I have tried just about every combination of CSS styles imaginable. Sometimes they worked great in 2-out-of-3 browsers… but then almost is never going to be good enough when it comes to websites, is it? That is where Javascript comes in. With it, we can create a robust solution that ALWAYS works and gives us predictable results every time.
Also, most of the current solutions out there only resize things at the time of the page load. This solution updates all the time, since there are times when you want a more expandable-contractable page design.

What This Tutorial IS NOT… 
This tutorial is meant to be a starting point only. All code has been commented inside the Javascript and XHTML, and CSS. You may copy-paste this code and use it for any purpose commercial, or private, as long as you are not selling the code itself and it is an integrated part of an actual webpage project not intended to solicit sales of this code.

Let’s Get Started 
To begin with, let’s introduce the technologies we will be using to achieve these automated, absolutely positioned columns of content. I decided to do everything in as few technologies as possible and using things that would be updated and open-source for a long time to come. I settled on Prototype.js for my cross-browser support, and CSS/XHTML for everything else. Prototype.js is a javascript-expanding system which is widely used, fully supported, and is ALWAYS being extended by others and updated. So, there is a pretty good chance that it will be around for years. The other nice thing about Prototype.js is that the code you need for your pages will reside on the same webspace as your site, and is not retrieved remotely, so if your page works now, it should work until your webhosting provider makes enough changes in their webserver configuration that it breaks your site. Besides, the average life-span of a website is typically 3-5 years. Anything beyond that is an amazing, unexpected bonus.

Prototype.js extends Javascript quite well, and it allows me to write smaller, faster code that is rather cross-browser compatible. So, I created my functions in an external javascript file and simply import them at load-time for use in my page.

Our Logic Flow 
What I needed was a container (wrapper) DIV that would hold multiple columns (DIV’s). Each wrapper-enclosed DIV would become a vertical column of content that would dynamically expand or contract its height according to how much content was enclosed. As the columns approached or receded from the bottom of the wrapper DIV, it would enlarge or reduce the height of the wrapper DIV so that our longest column maintained the same distance from the actual bottom of the wrapper DIV. Also, the page needs to be able to update itself upon load and anytime that a column changes height. Oh, yeah, and everything needs to be positioned absolutely so I could control the layout exactly the way I wanted it. I also wanted header and footer elements that could act as either visual spacers, or as holders for page-cap graphics. A lot of times, when I create a “page” of content within a web page, I like to give it a visual top and bottom so that it stands out more from the rest of the content on the page.

How We’ll do It 
We will accomplish self-updating columns by using an event listener for any click on the document. This will execute a function called “pageSnap” which will adjust the page_wrapper DIV height in relation to its contained column DIV’s. Also, instead of calling each column of content by name, we will simply create an array that holds every element of the class “page_column”. This will come in very handy later when you want to make your layout a 3, 4, 5… column layout. Since the columns are called by their class and not by their id, you can name the actual column DIV elements anything you like. They just need to be assigned to the class “page_column” to be included in the self-updating process of the wrapper DIV.

Our Page Structure 
Below is a simple diagram of how our DIV elements are structured. A copy of this diagram is included in the source code for this project. As you can see, all of the individual DIV elements that make up our page of content are contained in a single wrapper called “outer_wrapper”. While this wrapper is not necessary, it does gives us the flexibility to take the entire chunk of elements and simply drop them into a new page design. By enclosing all the elements together, it keeps them from spilling out into other page elements and interacting in an undesirable way.
The names of each element also correspond to that element’s CSS class definition. Since class and id do not share the same namespace, your browser should handle these just fine. If you do run into some future, unforeseen conflict, you can always change the class names in the CSS, just make sure you change them in the imported CSS file as well. I have been using duplicate class and id names for a while and have yet to have them conflict… but that does not mean it will stay that way forever.

Let’s Dissect Our Code 

Click here to see a working version of this example code.
Click here to download the source code.
Okay, so now you have the basic logic, the “why should I bother”, and the overall element structure down, so let’s move on to dissect our code block-by-block. But, first, let me tell you that I am only going to go over the relevant code blocks. I refrain from describing all the code in the Javascript, CSS, and XHTML files since they have all been thoroughly commented.

document.observe("dom:loaded", startup);

 1. This block of code assigns an event listener for the DOM event “loaded”. Since this fires before the onLoad event on the body element, it makes a great “pre-startup” startup handler. Just be sure to practice good-housekeeping and remove the listener after you no longer need it.

var pageWrapper, footer;
2. Here we add a couple of variables to the DOM for later use. We do not want to assign them to their respective page elements yet, because those have not been registered with the DOM yet and will simply return an undefined element, which will break the page and nothing will resize properly, or at all. Now, we do not have to create an instance of these variable names here, but it is good practice to do it this way, in case we want to add other functions that might use these variables. We could avoid globals altogether by placing our variables as properties on the element itself, but that is another article altogether. For now, we will keep things as simple as possible.

function startup()
// turn OFF the event listener?s
document.stopObserving("dom:loaded", startup);

// these are OPTIONAL and should be removed when you create your own layout
// they are only here to allow you to shrink and grow the test columns to see how the page functions.
// assign some listeners for our shrink/grow buttons
$('clickable_1').observe( 'click', function(myEvent) { stretchElement("20",myEvent) } );
$('clickable_2').observe( 'click', function(myEvent) { stretchElement("-20",myEvent) } );
$('clickable_3').observe( 'click', function(myEvent) { stretchElement("20",myEvent) } );
$('clickable_4').observe( 'click', function(myEvent) { stretchElement("-20",myEvent) } );

// get a handle for the page_wrapper main div holding your columns
// you could name your page_wrapper anything, just make sure you change the name here as well
pageWrapper = $('page_wrapper');

// assign a height offset value for out footer element. If it does not exist, it will return a zero height
try {
footer = $('page_footer').getHeight();
} catch(e) { footer = 0 }

// set up a listener for a click on the document since we do not know which elements will expand or contract out layout height
// we need to check every time for changes in the height of the pageWrapper DIV
document.observe( 'click', pageSnap );

// DON'T FORGET! You can update the page_wrapper height any time simply by calling this function.

3. This is the function that will run AFTER the page has loaded and registered all the page elements with the DOM. Now, we can assign our elements to their respective variables and thereby get a valid handle for later use. You will notice that there is a stopObserve method called on the document object. This is where we stop listening for the “DOM:loaded” event.

pageWrapper = $('page_wrapper');
4. Here, we assign our “page_wrapper” element to the global variable “pageWrapper”. This will give us access to that element without having to change the occurance of the element name more than once.

try {
footer = $('page_footer').getHeight();
} catch(e) { footer = 0 }

5. There are times that you may not want a footer element. You cold simply assign the element a height of zero, but for the sake of robust code, I wanted something that would allow me to remove the “page_footer” DIV altogether without breaking my page. So, if the element does not exist, it simply ignores the error and assign a height value of 0 to the variable “footer”.

document.observe( 'click', pageSnap );
6. Here is where we now add an event listener to the document element. This allows us to automatically check our “page_wrapper” height without having to call it from every function that might resize our “page_column” DIV elements due to a user click on some size-changeing UI element. You could just as easily assign this listener to the “page_wrapper” element instead of the “document” element. But, for the vast majority of purposes this works best.

7. Once the page loads, our “page_column” DIV’s may have already changed size due to font-size differences among browsers and font families. So, it is always a good idea to execute this function to make sure everything is adjusted right away.

function pageSnap()

// get a the object that was acted upon to get it to this function
var target = pageWrapper;

// calculate a starting prevHeight (previous height) of the page_wrapper DIV
var prevHeight = 0;//target.getHeight() - footer

// this creates an array of all child elements in the target parent (page_wrapper) that are of the class "page_column"
var targetKids = $( target ).select('[class="page_column"]');

// go through all page_column elements and adjust the page_wrapper DIV height
for(var index=0;index prevHeight )
target.setStyle({ height:String( (height + footer) + "px" ) });
// save our current height as the prevHeight variable for reference on the next "page_content" column
prevHeight = height;

8. This is the function that will make the actual column adjustments. For the sake of simplicity, I have assigned the “pageWrapper” handle to a new variable called “target”. Of course, you do not need to do this, but I like to reassign our global to a local variable so that there is only a single instance of my global in my function definition. Also, if I wanted to have this function work on multiple “page_wrapper” element in a single webpage, I would just have to assign our “click” listener to each “page_wrapper” instead of the document, and then assign the “wrapper” variable to the “this” variable which would give us a handle to whatever element called the function without having to track all the different names of a the different “page_wrapper” DIV elements.

var prevHeight = 0;
9. Here, we want to create a variable to hold the previous height of the last “page_content” column whose height we compared to the height of the “page_wrapper” element. I assign it to zero, simply because of we try to add it to another integer and then assign it the height style property of an element, it will break our page in some browsers. By setting its inital value to 0, it helps to guarantee that we do not get some erroneous starting value.

var targetKids = $( target ).select('[class="page_column"]');
10. Here is probably the trickiest part of our code. What the select method allows us to do is collect all the occurances of the “page_content” class into a single array that we can iterate through and compare each element individually to the height of our “page_wrapper” DIV.

for(var index=0;index prevHeight )
target.setStyle({ height:String( (height + footer) + "px" ) });
// save our current height as the prevHeight variable for reference on the next "page_content" column
prevHeight = height;

11. Here we create a loop that will iterate through all of the elements in our “targetKids” array. Now, we could have done this with an each method and assigned our function to each of the elements themselves in the array, but for the sake of simplicity, I decide to just use the tried-and-true for-loop. Unless you have many, many elements to be compared, you should not notice any really appreciable speed difference.

var kid = $( targetKids[index] );
12. Here we assign our first element in the array to a shorter variable name. There is just too much room for error to have to type, retype, or even copy-paste the long name of “$( targetKids[index] )” every time we need to reference it. The shorter your variable names the less chance of typos.

var top = parseFloat( kid.getStyle( 'top' ) );
var height = kid.getHeight();

13. Now, let’s get a floating-point version of the values stored in our style property “top” and “height” on the “kid” element.

if( height + top > prevHeight )
target.setStyle({ height:String( (height + footer) + "px" ) });

14. Now, let’s add the height of our “page_content” column to its “top” style value to get its actual height inside the “page_wrapper”. If our content is now taller than the holding DIV element, we adjust the height of the holding DIV to the same as the height of our “kid” element PLUS the height of our “page_footer” element. This will make sure our holding DIV stays taller than or “page_content” DIV.

prevHeight = height;
15. So, all we need to do now, is save the current height value for comparison against the height of the next element. Using this value gives us a simple way to make sure that if the next column is taller than the last, we need to increase our “page_wrapper” height. Otherwise, if the next column is shorter, we can simply ignore it and keep the “page_wrapper” height unchanged. This way, we do not need to compare every column to every other column every time we look at each column height.

16. Also, make sure that if you want to move your columns, or add columns, you duplicate the “page_column” DIV element, give it a unique instance “id” and override any “left” or “top” properties using an inline style definition. The default position for all columns in the CSS class definition for page columns is at top:0, left:0.


That is about it. Pretty simple, actually. But not necessarily obvious. So, I hope this tutorial has helped.
Download this article’s source code here.

Google, adWords, ActionScript 3, and Me

February 17, 2010

Please be aware that this tutorial is intended for intermediate-to-advanced ActionScript programmers and designers. It is therefore assumed that you have a competent understanding of the underlying principles and specifics of both versions of ActionScript. I cannot respond to all questions regarding this code. So, please assume that you are on your own. Notes, instructions, and any relevant documentation has been included in the FLA files. Also, you will need Flash CS3 or CS4 to read the source files included in this tutorial.

Q: How do you get Google’s adWords program to support ActionScript 3?
A: You don’t… well, sort of.

Recently I needed to create some banner ads of varying sizes that could be injected into Google’s adWords ad-delivery system. I diligently went to the link Google provides with the ad specs and read up on what sizes and formats were acceptable by Google.
I guess I should have read a little more carefully because I blithely created all my ad banners in AS3, assuming that since AS3 is more than four years old, it would be supported by Google. I use AS3 exclusively now because it is much more object-oriented and it uses an event-based architecture and offers me far more options than does the older, slower, less-efficient AS2 (ActionScript 2).
After I coded all of my banners, I submitted them to Google for approval and testing. The banners were pretty simple in architecture, so I figured they would be relatively trouble-free. Wrong. I received an email from my Google ad rep saying their system was rejecting the SWF banners… The reason (as you may have already guessed)? Their system does not currently support AS3, and there is no projected date for supporting it.

Big Trouble

Let me just say that I have always thought of Google as being a bit more on the cutting edge of technology than they turned out to be. When I say “cutting-edge”, I am not referring to the any of the latest-and-greatest technology. To me, this is what I would consider “bleeding-edge” technology. This is where the pioneers and beta-testers live. So, since AS3 is no longer bleeding-edge technology, I just assumed they were currently supporting it. Well, they don’t support it now and they do not have a plan to support it any time soon.

What to do?

So, rather than hurl myself off my chair, or spend hours recoding my ActionScript code into AS2, I decided to try and create a work-around that would allow me to submit a Flash AS2 SWF that would meet their restrictions, but would still allow me to leverage all of the goodies in an AS3 SWF for my client.
What I ended up creating was essentially a “lifejacket” for my ActionScript code: I created an AS2 SWF that acted as a loader and clickTAG value-passer to an AS3-based SWF that would be loaded into the same security domain and replace the older, AS2 SWF.
It was a bit tricky since Google has all kinds of code and function-call restrictions. They basically filter your SWF and look for any potentially “offensive” code. Hey, I completely understand the need to control the content that you are distributing for people… but there must be a better, more efficient way of handling this. Their current system needlessly punishes those of us who have a legitimate, innocuous use of more advanced functionality. Because of this fear of abuse, we the designers and programmers all have quite a few hoops to jump through to keep our work fresh and relevant. Besides, all of the ads require pre-approval of content before they can ever be launched, disseminated, or viewed by anyone so the chances of getting anything by Google (unless they just aren’t paying attention) are pretty much zero.
WARNING: Be careful what you try to build into your AS3 code. Never forget that Google has to approve your ad and if they do not think it is appropriate, at any time, working-or-not, they will shut it down, delete it, or just completely ban you from using their adWords service.


Okay, so I created my AS2 code to load in my AS3 code and run in the same domain, thereby meeting all of Google’s criteria and also my own. It really worked!… well, sort of. It was not a perfect solution yet. Google’s supplied “clickTAG” value was getting chewed up somehow in transition and so the ad was not going to the destination URL that it was supposed to go to. The new ad failed Google’s testing.

The Final Solution

I ended up solving my problems like this…
1. I placed Google’s clickTAG AS2 code into the first frame of an empty movieclip. This would act as my “button” for Google, but would not really be used, but it would allow any code search by Google to come up as successful.
2. I then had to create a URL string from some ascii character codes, since Google does not like to see URL prefix “http://&#8221; in their code. They are worried you will circumvent their pay-by-the-click system. I say, if you are willing to submit your source code to them and to be held up to scrutiny, then you should be able to include code like this, but they have a more binary policy. It is either acceptable or not. As long as you are not doing something malicious, there should be no problem. But beware those who have not-so-good intentions. Google isn’t a huge mega-corp for no reason. They could squash you, so be careful!
3. Once I programmatically created the URL string and captured the value of the clickTAG variable, I used a function to change all of the offending URL characters to something that could be passed along with the URL and would not be encoded, converted, or altered on its way to the newly-loaded AS3 SWF.
4. After the replacement SWF was loaded, I then used a regular expression (RegExp) and put back, all of the offending characters from the Google URl so it would now be functional again. [exoboy’s note: regular expressions (RegExp) are NOT available in AS2, are only in AS3, and are INDESPENSIBLE when dealing programmatically with strings!]
5. Now, if a user clicks on the SWF, they will be taken to the Google-generated link with all of Google’s tracking still intact.
6. That’s it! You can download the simple example source files here.

SWF add is loaded —-> SWF lifejacket preps Google clickTAG value —> SWF lifejacket replacement SWF —> replacement AS3 SWF re-assembles Google’s clickTAG value —> AS3 SWF runs and user clicks to visit banner owner’s site…
These steps solved all of my pre-flight issues with Google, and functioned perfectly upon actual distribution. Now, I will be able to do whatever ad banners I want in AS3 without having to be limited by the donkey-cart that is AS2.

What to Send to Google…

 The nice thing about this solution is that you only have to send the “lifejacket” SWF to Google for distribution. The actual banner AS3 SWF resides on your client’s domain. The lifejacket even meets Google’s size restrictions. My last lifejacket was only about 4K! All you need to remember is to make the name of the lifejacket SWF the same as the banner SWF, but with an additional “-lifejacket” before the “.swf”: e.g. my_banner-lifejacket.swf would be the lifejacket and my_banner-ad.swf would be the ad that you host on your client’s site.

An Important Note On Security Domains

Just remember, that in order to load an image or SWF from one domain to another, you must have the proper security settings in the SWF that is loading and the SWF that is being loaded. You also will need a properly-formed “crossdomain.xml” file that must be placed in the ROOT directory of the hosted website that you are loading your AS3 SWF from. Otherwise, your loaded SWF will never load or display properly. I have put security settings into the sample code that worked for me. You should start with these, but you may need to adjust them if they do not work for you.

Sign the Google AS3 Petition!

Click this link to be taken to and join the Google AS3 petition… if enough people demand AS3 in their adWords program… who knows? Maybe they might even think about it.

Copyright 2010

LIFEJACKET™ code and concept by Clarence “exoboy” Bowman
©2010 Clarence “exoboy” Bowman, all rghts reserved You may use this code for anything except resale, provided this copyright info remains embeded in the source code, and credit is given in any documentation.