Site Navigation Menus, Pure Actionscript & FlashDevelop

A recent requirement at work had me having to forgo Flex for a Flash project. I'm replacing a DHTML site navigation system that employs several images, javascript libraries and, more importantly, places over 70 links onto any given page of the site. I've inherited the job of cleaning up the site SEO-wise and all of these links prevent me from cleanly sculpting the site. At the same time, I am working on improving the performance of the site, and, soon, improving the functionality of the navigation.

Anyway, while I like Flex - really, I like Flex, we need to get a room or something - she can be too heavy for some tasks, and the thought of dropping over 100KB of Flashy goodness on everything single page of the site is less than desirable. Instead, at my current level, I am more than halfway there just using a pure Actionscript Flash project and I have kept my SWF size down to under 4KB. Keep in mind, I am using an XML supporting doc that adds 7KB or so, but I would use the same file for Flex or Flash.

Also, I decided to really try the FlashDevelop Actionscript IDE for a full project and have been really pleased with its performance. The template boilerplate was very helpful, this is my first non-Flex project, the code hinting very helpful. Since the flash menu/navigation system I built involves resizing itself on the fly using the flash.external.ExternalInterface.call() function, I had to develop live (somebody let me know if there is a better way), so I really didn't get a chance to test FlashDevelop's debugging tools. Anyway, FlashDevelop really shows that an open source toolset, even one based on .NET, can really be a powerful option.

I mentioned a navigation system, let's move on to that. The DHTML system that I am replacing uses drop down menuing, with cascading sub-menus. More importantly, at least from a Flash perspective, is that it overlays other content on the site. I was fretting this requirement as, usually, my Flex apps stay quite contained within a nice, constant rectangle.

It turns out that it wasn't so bad. I mentioned the flash.external.ExternalInterface.call() function, that's one I'll be adding to my Flex toolkit for certain. With it, I can communicate with Javascript on the page. In this case, I keep track of the size of my menu, and just request a very simple javascript function to resize the div in which SWFObject placed my SWF.

My Javascript looks like:

function changeFlashSize(newSize) {
menu = document.getElementById("swfContainer");
menu.style.height = newSize + "px";
}

Make sure that you rename swfContainer to whatever label you are using for your <DIV>'s id.

The Actionscript to access this function is really simple too:

import flash.external.ExternalInterface;

var swfHeight:int = 22; // value, in pixels, of the new height of the swf

flash.external.ExternalInterface.call("changeFlashSize", swfHeight);

A couple of other thoughts:

  • make sure to set the wmode="transparent"; without that your swf will be opaque and cover anything beneath it; probably not the effect you were going for
  • with the wmode="transparent", the swf will obey normal dhtml z-index rules, so either add your swf last, or explicitely set its z-index

The project is still underway, but it does make me appreciate the hard work that has gone into the Flex project. It is so easy to take everything for granted until you want to identify a sprite by id, and there isn't an one. Also, in general I think this has been a tremendous exercise as I am starting to really feel the need for many of the things OOP provides. For instance, I discovered that, for reasons of polymorphism, I should have created a base menuItem class from which the subMenus inherit. This would have made life easier with my eventListeners - I implemented a very simplistic id property for my classes that I use to keep track of my menuItem and subMenu instances. In order to access their id property, I have to cast it to its class type, but since they are two distinct classes, I can't substitute one for the other, even though I am looking for the same property in each instance. My work around was to create two eventListeners that effectively do the same thing, but cast to different classes. That is to say, it's ugly and inelegant.

One last thought on pure Actionscript development with FlashDevelop, I had trouble accessing some constants. Now, it very likely was my fault as I am trying to get this project done ASAP, but two things had to be fixed, and normally I would use constants to do it instead of the actual value. However, it was important to turn off scaling and ensure that everything was aligned to the top left. If you don't set the alignment, the floating during resizing is enough to drive one insane. Anyway, the following lines would be well placed in your constructor:

stage.scaleMode = "noScale"; // oddly, it turns off scaling; crazy
stage.align = "TL"; // sets everything to be positioned in the TopLeft

I will hopefully have an example up soon, there are some more milestones I want to achieve first, but I would very likely be willing to share source code if anyone wants to see it.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
BlogCFC was created by Raymond Camden. This blog is running version 5.9.1.001. Contact Blog Owner