Actionscript 3 call a javascript function - javascript

is it possible to call javascript functions inside flash (as3)? How about not in the same domain? Can you provide an example snippet for samedomain and not same domain?
thanks!

Using the ExternalInterface you can communicate with JavaScript from Flash, however only in the window where the Flash application is running.
It is as easy as doing:
ExternalInterface.call("jsFunctionName", argument, argument, ...);
To do the reverse (calling Flash from JavaScript) you do the following first:
ExternalInterface.addCallback("jsFunctionName", callbackFunction);
function callbackFunction(arg:String):void {
trace(arg);
}
And then you can call jsFunctionName("foo") from JavaScript.
See the adobe docs for more info on that.
As for your cross domain, you can't as far as I know, but you may be able to proxy the call via your server.

Related

ExternalInterface addCallback repeatedly fails

I'm trying to get JS in a Wordpress webpage and an Actionscript 2 Flash movie to talk to one another. The attempt is failing miserably. On every attempt to call the function that I've set a callback for, I get "..... is not a function" in the browser error console (I'm using Firefox 20).
Here's how things are set up:
The page is a bit unusual, being a Wordpress page with inline javascript. The main javascript is a jQuery.ready() block of code that loads the flash object (this is done so that GET parameters in the URL can be passed into the flash). Once it's loaded, there's a link with this:
Region A
Meanwhile, the flash object has this in it to make it possible:
import flash.external.ExternalInterface;
System.security.allowDomain("thisdomain.com"); // the domain on which the flash is hosted
ExternalInterface.addCallback("setRegion", null, switchZone); //switchZone is the function's internal name
The flash's container has allowScriptAccess set to "always", and I can confirm that the jQuery statement is hitting the right target. However, when the flash object is debugged, the addCallback returns false— a sign that it's failed. Anyone have any ideas what could be going on?
I met this kind of problem before. To explain this, you may just image your flash file to be a image. Usually, the image in you page will show after the whole page is loaded. For your flash file, in $.ready event, the flash DOM is inserted into your page, but the content of it is loading and the environment of it is not ready yet.
To handle this, you need to register a callback function in your page like this:
window.ping = function () {
$('#fmap')[0].setRegion('regiona');
}
Then in your flash environment, call the ping() registered.
The order of function call is the key point here.
OK, figured it out. First off, the function declaration needed to be above the ExternalInterface.addCallback bit. In addition, once that was done it started throwing a different error, so I had to make a new function... thanks for your help.

Catching an ExternalInterface call to a non-existing function

I have about 1000 SWF files all calling JavaScript functions through ExternalInterface.
I do not have access to these files source files, and have no way of editing them.
My basic problem is that that they are all calling different functions and the Flash AS3 script hangs until it gets a response from the function.
What I am hoping to do is detect what the functions which are being called from the SWF files in JavaScript and then create the function on the fly, however, in order to do that I would need to detect the function being called first.
Is there any way to do this in JavaScript?
No, that's not possible in JavaScript.
I dont know how much variation there is, but is it an option to use a decompiler on several swf's just to see which ExternalInterface calls are called? Try online decompiler http://www.showmycode.com/
You can catch undefined errors from Flash using UncaughtErrorEvent
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/UncaughtErrorEvent.html
I dont'tknow if javascript is throwing errors? You could catch the errors from javascript too, using window.onerror
https://developer.mozilla.org/en-US/docs/DOM/window.onerror
Could you explain how much control you have over the SWF files and what exactly is it you want to achieve?
Are these AS2 ou AS3 ?
Is there a main SWF file loading these SWF files ?
I was looking at the docs and it seems that using ExternalInterface.marshallExceptions in conjunction with UnhandledErrorEvent, you may detect unexisting function calls from the Flash side.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html#marshallExceptions

Javascript and Flash in AS3

Is it possible to use Javascript in flash. For example, as a simple test I am trying to use Javascript's alert method when a button is clicked.
I am using AS3. Is it possible?
Like Marty mentioned, you can use the ExternalInterface class to execute a Javascript. Your options are to execute a function embedded in the (html) page code and create one from scratch. Because alert is a default function you can use its name as the first parameter for the call method (of ExternalInterface) and the string as the 2nd one.
If you provide a single parameter, you might wanna write a function instead to execute (or return) something.
btn.addEventListener(MouseEvent.CLICK, btnClicked);
function btnClicked(e:MouseEvent):void {
ExternalInterface.call("alert","something");
// or
ExternalInterface.call("function(){alert('something');}");
}
No.. Flash uses ActionScript 3.
You can call a JavaScript function on the same page as an embedded SWF using ActionScript's ExternalInterface class, though.
A quick demo on implementing ExternalInterface:
if(ExternalInterface.available)
ExternalInterface.call("alert", "Hello!");
Tip: ExternalInterface calls will not work locally unless you add the location of the project in this security settings panel and check "always allow".

Silverlight 4 MVVM: Call Javascript function from viewmodel

we have developed an Intranet Management Application with Silverlight 4. We have been asked to add the functionality to call a remote desktop tool which is installed on clients using the Intranet SL App. In an earlier version of the tool written in ASP.NET we just added a Javascript function to the aspx page like this:
function RunShellCommand()
{
var launcher = new ActiveXObject("WScript.Shell");
launcher.Run("mstsc.exe");
}
and called it from ASP.NET.
Now it's clear that SL4 is running in a sandbox and that I cant use the AutomationFactory to create a WScript.Shell object (out of browser mode is not an option).
I thought I could circle around the problem by, again, adding the RunShellCommand javascript method in the aspx page where the SL4 control is hosted and call it via
HtmlPage.RegisterScriptableObject("Page", this);
HtmlPage.Window.Invoke("RunShellCommand", "dummydata");
from my ViewModel. When I run the Application the debugger just skips the RegisterScriptableObject method and quits. Nothing happens.
My question is if am doing something wrong or if this just wont work this way.
Is it possible that I cant do a RegisterScriptableObject from a viewmodel?
EDIT: When I explicitly put a try, catch block around the two methods I get an ArgumentException from the first method stating that the current instance has no scriptable members. When I delete the first method and only run the Invoke, I get a browser error stating that the automation server cant create the object. So is there really no way (except OOB mode) to do this?
Yes, the explanation is correct: you should add at least one method with the ScriptableMember attribute in order that you can use the RegisterScriptableObjectmethod. But it is used only for calling C#-methods from JavaScript.
As far as I see, you want to do the opposite: to call JavaScript code from the Silverlight application. Then you need only one line:
HtmlPage.Window.Invoke("RunShellCommand");
The error automation server cant create the object has nothing to do with Silverlight. I'm sure that if you call the JS function directly - the error will remain.
According to the internet, the reason might be not installed Microsoft Windows Script. Or it is because of security restrictions of the browser.

Calling a flash external interface AS3 function on page load

I have a function defined in AS3 that's gonna be called from client side via JavaScript. The AS3 functions simply print some value on SWF screen when it's called.
It works fine when I set an onclick event handler to a button and call the AS3 function. However I want to call this AS3 function as soon as the page loads. I am using jQuery in the project and I placed the call to the AS3 function inside $(document).ready(), but that gives me the following error in FF2 firebug:
getFlashMovie("my_movie_name").my_as3_function is not a function
Then, I tried calling the by setting an onLoad event handler on the , but that also does not work - produces the same error.
So, my question is, how do I call an AS3 function automatically once page loads? In my project, I need to pass some client side initialization information to the flash once page loads.
You'll need to have your flash call a function in the page to notify it that the Flash is loaded and initialized, then use that as your entrypoint.
In the flash:
ExternalInterface.call('flashReady');
In the page:
<script>
function flashReady() {
..
}
</script>
If you use swfObject to embed your SWF (probably a good idea anyway) then you can use its addDomLoadEvent() function which allows you to do something once the SWF is fully loaded
swfobject.addDomLoadEvent(function() {
$("#swfobject").get(0).inited('you are loaded!');
});
i am not trying to be a wiseguy here but do you test your work on a server?
external interface, addcallback dose not work on local filesystem, and eventually you may have to add:
flash.system.Security.allowDomain('http://localhost');
if you are running on local.
:P
The problem is that the Flash object is not initialized yet when the page finishes loading. It would probably be much safer to perform this initialization from within AS3. If you want to pass values from the HTML page, use flashVars.
I ran into this problem myself a couple of weeks ago. The solution is pretty simple :)
First, you need to put in your DOM a div
<div id="timewriter"><div>
You'll also be using the jQuery Timers plugin to time your loading. After this preparation the things will go very easy.
The following piece of code will go in your $(document).ready();
var movie = getFlashMovie('my_movie_name');
if(movie.PercentLoaded() != 100)
{
$("#timewriter").everyTime(100, function ()
{
if(movie.PercentLoaded() == 100)
{
$("#timewriter").stopTime();
//the movie is loaded, call here your functions; usually this happens if you don't use cache
}
});
}
else
{
//the movie is loaded, call here your functions; usually you get here if you use cache
}
Later edit: be careful that HTML page load doesn't mean the swf was loaded, that happens right after the web page load complete event. Also my solution is based on jQuery javascript library.
Answers by both tweakt and Bogdan are viable. Use tweakt's method if you have access to the Actionscript. Use Bogdan's if you don't. I was looking for an alternative besides polling (when you don't have access to the Actionscript) but I have been unsuccessful in finding one thus far. Events are mentioned here: http://www.adobe.com/support/flash/publishexport/scriptingwithflash/scriptingwithflash_03.html But noone seems to know how to use them.
For the sake of completion, you would also have to use import flash.external.*; to make everything work.
It seems like the collection of answers offered answers this closest to it's entirety.
As David Hanak said, the flash object cannot be accessed yet because it is initializing, though i disagree that we must rely on flashvars, though I love them.
Tweakt is right, but upon calling the function in the javascript, have that call the javascript function that calls back to your swf; This way we know flash is ready as it sent the first call.

Categories