addCallback(ExternalInterface.addCallback 方法)
public static addCallback(methodName:String, instance:Object, method:Function) : Boolean
将 ActionScript 方法注册为可从容器调用。成功调用 addCallBack()
后,容器中的 JavaScript 或 ActiveX 代码可以调用在 Flash Player 中注册的函数。
可用性:ActionScript 1.0;Flash Player 8
参数
methodName:String
- 从 JavaScript 调用 ActionScript 函数时可使用的名称。此名称不必与 ActionScript 方法的实际名称匹配。
instance:Object
- this
在该方法中被解析成的对象。此对象不一定是在其上可找到该方法的对象,您可以指定任何对象(或 null
)。
method:Function
- 要从 JavaScript 调用的 ActionScript 方法。
返回
true
- 如果调用成功,则返回 Boolean
。如果调用由于下列原因而失败,则返回 false
:实例不可用、遇到了安全限制、没有这种函数对象、发生了递归或类似情况。
返回值为 false
还可能表示包含环境属于调用代码无权访问的安全沙箱。您可以在包含环境的 HTML 中为 allowScriptAccess
OBJECT
标签或 EMBED
标签设置一个合适的值,以解决此问题。
示例
下面的示例将 goToMacromedia()
函数注册为可使用名称 goHome
从容器调用。
- import flash.external.*;
- var methodName:String = "goHome";
- var instance:Object = null;
- var method:Function = goToMacromedia;
- var wasSuccessful:Boolean = ExternalInterface.addCallback(methodName, instance, method);
- var txtField:TextField = this.createTextField("txtField", this.getNextHighestDepth(), 0, 0, 200, 50);
- txtField.border = true;
- txtField.text = wasSuccessful.toString();
- function goToMacromedia() {
- txtField.text = "http://www.macromedia.com";
- getURL("http://www.macromedia.com", "_self");
- }
为了使上一示例能够正常运行,应复制以下代码并将其粘贴到包含 HTML 页中。此代码依赖 OBJECT
标签的 id
属性和 EMBED
标签的 name
属性以获得值 externalInterfaceExample
。由于 Internet Explorer 和 Netscape 以不同方式引用 movie 对象,所以函数 thisMovie
根据浏览器返回相应的语法。除非服务器上承载 HTML 页,否则您的浏览器可能会出现安全警告。
注意:请避免使用访问插件对象的其它方法(如 document.getElementById("pluginName")
或 document.all.pluginName
),因为这些其它方法在所有浏览器上的运行不一致。
我很好奇这个函数是怎么和javascript交互的。经过仔细探索,我发现当在flash中第一次调用ExternalInterface.addCallback 的时候execScript了以下内容:
- <form>
- <input type="button" onclick="callExternalInterface()" value="Call ExternalInterface" />
- </form>
- <script>
- function callExternalInterface() {
- thisMovie("externalInterfaceExample").goHome();
- }
- function thisMovie(movieName) {
- if (navigator.appName.indexOf("Microsoft") != -1) {
- return window[movieName]
- }
- else {
- return document[movieName]
- }
- }
- </script>
function __flash__arrayToXML(obj) {
var s = "<array>";
for (var i=0; i<obj.length; i++) {
s += "<property id=/"" + i + "/">" + __flash__toXML(obj[i]) + "</property>";
}
return s+"</array>";
}
function __flash__argumentsToXML(obj,index) {
var s = "<arguments>";
for (var i=index; i<obj.length; i++) {
s += __flash__toXML(obj[i]);
}
return s+"</arguments>";
}
function __flash__objectToXML(obj) {
var s = "<object>";
for (var prop in obj) {
s += "<property id=/"" + prop + "/">" + __flash__toXML(obj[prop]) + "</property>";
}
return s+"</object>";
}
function __flash__escapeXML(s) {
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
}
function __flash__toXML(value) {
var type = typeof(value);
if (type == "string") {
return "<string>" + __flash__escapeXML(value) + "</string>";
} else if (type == "undefined") {
return "<undefined/>";
} else if (type == "number") {
return "<number>" + value + "</number>";
} else if (value == null) {
return "<null/>";
} else if (type == "boolean") {
return value ? "<true/>" : "<false/>";
} else if (value instanceof Date) {
return "<date>" + value.getTime() + "</date>";
} else if (value instanceof Array) {
return __flash__arrayToXML(value);
} else if (type == "object") {
return __flash__objectToXML(value);
} else {
return "<null/>"; //???
}
}
function __flash__addCallback(instance, name) {
instance[name] = function () {
return eval(instance.CallFunction("<invoke name=/""+name+"/" returntype=/"javascript/">" + __flash__argumentsToXML(arguments,0) + "</invoke>"));
}
}
function __flash__removeCallback(instance, name) {
instance[name] = null;
}
而每次调用ExternalInterface.addCallback 的时候都会运行js的__flash__addCallback。这里要注意,instance参数就是网页上的插件,对于IE来说,是一个实现了IDispatch的ActiveX控件,这个控件有一个方法,即CallFunction,该方法就可以调用flash中的函数了。