Flex IFrame – Web browser in flash (update)
You can not have a web browser inside your web flash applications right? Well, you can! This solution uses html iframe to generate fake build in browser. So the behaviour of the browser in flash is the same as the one you are previewing this flash in (it is the same one). The best part of it is, you can manipulate with the position and size of this browser directly from flash. sk.yoz.html.IFrame solution was inspired by Alistair Rutherford, www.netthreads.co.uk.
- sk.yoz.html.IFrame
- FlexIFrame.js
- Application
- Application html
Flex Iframe application
Core of this thing is sk.yoz.html.IFrame class. It extends Canvas that is used to inherit properties and methods for positioning and sizing. There is one in order to make it work – every IFrame element must have id!
package sk.yoz.html { import flash.events.Event; import flash.external.ExternalInterface; import flash.geom.Point; import mx.containers.Canvas; public class IFrame extends Canvas { public var methodResize:String = "FlexIFrame.resize"; public var methodMove:String = "FlexIFrame.move"; public var methodNavigate:String = "FlexIFrame.navigate"; public var methodVisibility:String = "FlexIFrame.visibility"; public var positionChanged:Boolean = false; public var sizeChanged:Boolean = false; private var _autoResize:Boolean = false; private var _url:String = ''; public function IFrame() { super(); addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler) } override public function set id(value:String):void { super.id = value; } protected function addedToStageHandler(event:Event):void { positionChanged = true; sizeChanged = true; invalidateProperties(); } public function set autoResize(value:Boolean):void { _autoResize = value; if(value) addEventListener(Event.RESIZE, autoResizeHandler); else removeEventListener(Event.RESIZE, autoResizeHandler); } public function get autoResize():Boolean { return _autoResize; } protected function autoResizeHandler(event:Event):void { positionChanged = true; sizeChanged = true; invalidateProperties(); } override protected function commitProperties():void { super.commitProperties(); if(positionChanged) { var point:Point = localToGlobal(new Point(0, 0)); callJS(methodMove, point.x, point.y); positionChanged = false; } if(sizeChanged) { callJS(methodResize, width, height); sizeChanged = false; } } public function set url(value:String):void { _url = value; callJS(methodNavigate, value) } public function get url():String { return _url; } protected function callJS(method:String, ... values):void { if(!id) throw new Error("IFrame id is not defined"); var args:Array = [method, id]; try { ExternalInterface.call.apply(ExternalInterface, args.concat(values)); } catch(error:Error) { trace(error.message); } } override public function set visible(value:Boolean):void { super.visible = value; callJS(methodVisibility, value); } override public function set width(value:Number):void { super.width = value; callJS(methodResize, value, height); } override public function set height(value:Number):void { super.height = value; callJS(methodResize, width, value); } override public function set x(value:Number):void { super.x = value; var point:Point = localToGlobal(new Point(0, 0)); callJS(methodMove, point.x, point.y); } override public function set y(value:Number):void { super.y = value; var point:Point = localToGlobal(new Point(0, 0)); callJS(methodMove, point.x, point.y); } } }
FlexIFrame.js is JavaScript file. It uses your flex IFrame id from to create (html iframe) or use html element (any element) with the same id (id in flash = id in html). So you can use your prefabricated html elements (banners etc).
var FlexIFrame = { get: function(id) { var iframe = document.getElementById(id); if(!iframe) return FlexIFrame.create(id); return iframe; }, create: function(id) { var iframe = document.createElement('iframe'); iframe.id = id; iframe.frameborder = 0; iframe.style.position = "absolute"; iframe.style.zIndex = 1; iframe.style.border = "none"; document.body.insertBefore(iframe, document.body.firstChild); return iframe; }, resize: function(id, width, height) { var iframe = FlexIFrame.get(id); iframe.style.width = width + "px"; iframe.style.height = height + "px"; }, move: function(id, x, y) { var iframe = FlexIFrame.get(id); iframe.style.left = x + "px"; iframe.style.top = y + "px"; }, navigate: function(id, url) { var iframe = FlexIFrame.get(id); iframe.src = url; }, visibility: function(id, visible) { var iframe = FlexIFrame.get(id); iframe.style.display = visible ? "block" : "none"; } }
This is simple applicationion presenting draggable TitleWindow with “web browser” inside:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="init()" xmlns:html="sk.yoz.html.*"> <mx:Script> <![CDATA[ private function init():void { go(); } private function go():void { iframe.url = iframeURL.text; } private function mouseDownHandler():void { container.startDrag(); container.addEventListener(Event.ENTER_FRAME, enterFrameDrag); } private function mouseUpHandler():void { container.stopDrag(); } private function enterFrameDrag(event:Event):void { iframe.positionChanged = true; iframe.invalidateProperties(); } ]]> </mx:Script> <mx:TitleWindow id="container" layout="vertical" width="300" height="300" mouseDown="mouseDownHandler()" mouseUp="mouseUpHandler()" > <mx:HBox width="100%"> <mx:TextInput id="iframeURL" text="http://blog.yoz.sk" width="100%" enter="go()"/> <mx:Button label="Go" click="go()"/> </mx:HBox> <html:IFrame width="100%" height="100%" id="iframe" autoResize="true"/> </mx:TitleWindow> </mx:Application>
Finally do not forget to add flexiframe.js into your .html file:
<html> <head> <script type="text/javascript" src="js/flexiframe.js"></script> ...
Update (Feb 8, 2010): flexiframe.js resize() method uses style property for width and height (instead of original html element width, height)
Hello from Russia!
Can I quote a post “No teme” in your blog with the link to you?
sure
[…] post connects my 3 previous posts: Flex IFrame – Web browser in flash, FacebookLogger and Facebook Extended Permissions With Authorization by Overriding Class in swc in […]
[…] import flexiframe.js used for positioning html input on correct […]
Hey Jozef.. yeap you are right! we can have HTML on our flash apps.. but the IFrame is the wors’t thing we can have in a Flex app, why? Because all PopUps will remain behind the IFrame, you have to implement workarounds like hiding the IFrame if a PopUp has to show, other little terrible thing, is that you have to relocate the IFrame if your browser is resize.
That’s why I’m against the IFrame.. so for everybody who reads this, if you don´t really have to render HTML in your app, don´t do it.
Hi Pedro, thanks for your comment. I think you misunderstood the whole example and aim of this Class. It does not mean that all your PopUps are gonna be raplaced by HTML iframe. HTML iframe only overlaps the sk.yoz.html.IFrame class! Its aim IS to show iframe positioned and sized over this element. There is no workaround needed for hidding etc. You can hide it using IFrame.visible = false. Yes, you are right that in specific case (when your flash app extends with browser resize), you need to call:
iframe.positionChanged = true;
iframe.sizeChanged = true;
iframe.invalidateProperties();
it is meant to be used that way
whats more, sk.yoz.html.IFrame, can be used for positioning any other html element, see some examples here:
http://blog.yoz.sk/2010/02/textinput-wmode-opaque-transparent-workaround/
http://blog.yoz.sk/2010/01/elegant-facebook-login-for-desktop-application/
hi..
im trying to do this a lot of time in my websites,
you can download rar file that include all works?
thanks
@bar just copy paste content of these 3 files + add .js line into your main html wrapper thats all
It works!
Thank you for this post. It helped me a lot.
Its really great !Excellent work.I had implemented this to my project.
hi friend,First of all i would to thank you for sharing this app. i m using ur app inside a tab.Its working.But whats d problem is when i move to other tabs its still visible.i cant make it invisible.how can i use it as normal ?
expecting your reply
Thanks and Regards,
Sreeja.T
Hi sreeja,
use iframe.visible = false in order to hide the iframe, what it does is:
1. it hides mxml element in flash
2. it calls javascript and set iframe.style.display = “none”
Hi there,
Im viewing this site with FF 3.6 on WXP and the iFrame positioning is off, x + 100px and y + 100px more or less.
Just so you know!
peperone, everything ok here on 3.6.11, anyway you can make your own .css files or .js files to handle position
this is interesting, i just ask if this can run from a flash project not from a html??
or should it always run from a page?
weird…i wrote something here but can’t find the post….could this be applied in a flash project? in the fla not html? thanks a lot
@milton, this thing requires iframe/html. You can not make it work from standalone .swf, however you can use HTMLLoader http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/html/HTMLLoader.html in AIR projects. … all post from new users waits for my approval
Hello
This looks amazing! Thank you for this, but I am unsure how to use it properly.
I understand that there is a separate Actionscript file which I believe my .SWF would call and a separate Javascript file, but am unsure where the application code for the draggable window goes.
Also, how would I build a basic flash file that calls on the actionscript to load html in the IFrame?
I have spent a couple days trying to figure this out and any help would be greatly appreciated.
Thanks,
Daniel
Hi Daniel,
With flash builder create an flex project. Set SDK compiler to be compatible with flex 3 SDK (this post is 15 months old). Put into main application file all the code starting with “http://classes.yoz.sk/sk/yoz/html/IFrame.as and put it into src/sk/yoz/html/IFrame.as. Download .js file and place it into html-template dir, open your html wrapper and put reference to this .js file as described. Now build the project.
Daniel, this blog is not for beginners, if it takes you days to make this simple thing work, maybe you should start with some flex tutorials
Thank you. I appreciate it.
I have been working in simple flash for years, but there is a whole other level I have no idea about.
I’ll look into some tutorials.
Thanks again!
I appreciate the idea. But it doesn’t work. I don’t no what I miss. please make it clear what i do to use ion my project.
thanks in advance
Yirgu, does the example on this page work for you? The example is now almost 2 years old. mx components are not cool anymore, thus you need to rewrite canvas to group or something simplier. all sources are available in the article, just take a look again and go step by step
I read the blog and tried the code, but I’m very confused on how to go about it. Is there a video tutorial on how to insert a web browser into a Flash file to create the whole effect. Please let me know.
Yirgu, Flash Expert 83 have a look on http://blog.yoz.sk/2009/10/flex-iframe-web-browser-in-flash/comment-page-1/#comment-4470
Will it work with Action Script 2.0?
How do I use it? I dont see the part where it talks about the fla file. thx
Please email me if you can.
Matt, flex is only for actionscript 3.0
hi, what softwares will i use to make this? and can i place it inside a flash projector? 🙂
Daniel, its basicaly an iframe positioned on top over flash. You can not do this in projector but you can use http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/controls/HTML.html in air
Daniel good afternoon. Firstly thank you for your work.
Took a few days researching the topic of Flash Builder 4.6 iFrames from
Toas the solutions I’ve seen are not good or do not work.
In Fles 4.5 if they do but I do not use that version.
I really liked your approach to the solution, and we have implemented.
It works fine in Firefox but does not work in Internet Explorer (if there are people who still use it lol) and also in chrome, which opens web browsing but not the url.
I need this, is a matter of life or death, as quermeos call tinymce in that iFrame.
I would appreciate your help, or if you know a better solution I’d appreciate it infinitely.
Work as a freelancer?
infinite thanks
Atentemante
FreddyKrueger
Hi Jozef – this is a great component you have here.
Do you have a built-in way to communicate from Flex to the HTML page displayed in the iFrame? I have some Javascript functions on the HTML page I want to display in the iFrame that I want to be able to call from my Flex application. Would the callJS function serve this purpose?
hi Jason,
yes, you should be able to communicate with javacsript between parent window and child iframe (thus from flex to iframe). It will be propably restricted to a domain so both pages must be loaded from the same one etc. have a look here http://stackoverflow.com/questions/251420/invoking-javascript-code-in-an-iframe-from-the-parent-page
You can use ExternalInterface to execute javascript from flash.
Can someone help me with this. I am newbie to Flash builder 4.6 i want to embed a box with an html page (a google map page)
I am wanting to build a web app…I have built a simple program that has buttons and goes between states and now I just need to embed an html page…I have read up on iFrame but I don’t understand what to code….any help ?
Thanks
hi Tam. what the code does it creates html iframe and use absolute position to overlay it on top of flash
hi,
Nice post. But what if I want to load html content to this iframe instead of loading url. I dont know if it is possible with this . if yes then how ?
Thanks 🙂
works perfectly!
How can i use multiple iframes id ?
i bet its simple tho i am kinda newbie to flash builder, i have experience in as3 and a bit java, maybe you can direct me to what i should be concentrate my learning on to understand all of this better?
Thanks!!