The problem with embedding flash/flex components in web pages is that you must specify the viewport of the ‘movie’ and it’s tough to change it. That’s fine for flash movies, as they’re mostly movies. But Flex apps may need to change their size depending on what type of workflows they implement. I figured it would be a tough nut to crack: we’d need to trap resize events, and then call out to javascript in the embedding html page to resize the viewport appropriately. Not the hardest thing in the world, but I didn’t look forward to writing all that javascript.
Until I found out the coolest technique evar: you write your Javascript in an XML tag in your Flex code, and then inject that Javascript out into the browser at runtime and call it. That’s cool shit right there, friend. Big, huge ups to Noel at doesnotcompute for creating a reusable object that encapsulates this behavior: BrowserCanvas. Noel’s examples are really illustrative, but they are Flash-oriented so I had to do a little re-jiggering to use the lib in my existing Flex code.
Note: the widget I wanted to embed was a workflow nicely encapsulated in a single component, so I was able to easily add the item to the application at runtime rather than to write out the mxml. The toughest thing was just trying to figure out where to init the BrowserCanvas class, as I didn’t know exactly where the stage was available in the Flex Application life cycle. I ended up hooking into addedToStage and it worked fine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | private var canvas:BrowserCanvas; private function onAddedToStage():void { AnalyticsManager.instance.initTracker(this); canvas = new BrowserCanvas(stage,"Shopping"); addShopView(); } private function onResize(event:ResizeEvent):void { if( canvas ) { var shopping:ShopForPlansView = event.currentTarget as ShopForPlansView; canvas.height = shopping.height.toString(); } } private function addShopView():void { var shopping:ShopForPlansView = new ShopForPlansView(); shopping.id = "shop"; shopping.percentWidth = 100; shopping.addEventListener(ResizeEvent.RESIZE, onResize); addChild(shopping); } |
The other issue I had to deal with was that I needed to explicitly pass the name of the object/embed objects that embedded the swf in the html page (“Shopping” in this case). The example at Noel’s website somehow figures it out automagically.
I also can’t end the post without shouting out the inspiration for the BrowserCanvas: this post on actionscript.org. It’s a really good read that lays out the idea behind Javascript injection from the flash/flex runtime. A fantastic read.
{ 2 } Comments
This is interesting. I want to know if this will help me with the problem I have. I have a flex app that is placed on a page that has a 100px header in html. The flex swf file then appears below this header and has width=100%, height=100%. The problem is that the swf file ends up going below the browser viewport by 100px. Is there anyway to make the swf file only fit the viewport, and secondly, have it resize it’s height to the viewport height when the browser window is resized?
Any help with this would be greatly appreciated.
Thanks,
Randy Leinen
The best thing there might be an iframe (sob!), though I’d have to play with the settings to be sure.
Post a Comment