[AS3]as3中保证ExternalInterface的可用性的四个方法
很多flash和js同学在页面接入flash的时候,都会碰到调用flash注册给外部的方法失败的问题。现在总结几种情况:
1,ExternalInterface.call失效问题:
1.1 没有动静,不生效,没反应(这么诡异的标题描述其实是在做seo,方便大家google到我们这里,木哈哈)。
这个问题不太明显,主要原因是因为“不报错”!例如我们在flash内部ExternalInterface.call(“jsFun”);而jsFun里面的js语句是出错的话,页面是没有任何的提示的。就会让很多人不知所措,以为flash的调用不生效。我们可以理解为flash在调用jsFun时会隐式的给内部实现包一层try catch,即:
//原来的代码
function jsFun() {
//your code here
}
//实际运行的代码,可以想象try catch是flash动态生成的
function jsFun() {
try {
//your code here
} catch(e) {}
}
从而导致没有任何反应。
解决办法:把错误信息暴露出来方便调试,我们可以写成如下形式:
//把flash的调用“跳”出来到js的环境里,出错的语句就出来了。
function jsFun() {
setTimeout(function() {
//your code here
},0);
}
1.2 swf与页面html文件不同域,js的allowScriptAccess限制导致报错
这种错也不明显,因为这个会在flash内部出错,如果flashplayer不是debug版本,就会导致出错信息不弹出。所以首要先推荐安装一个flashplayer的
安装一个DEBUG版本的flashplayer,马上就会显示“xxxxx下的swf不能调用xxxxx下的方法”。
解决办法:只要根据需要,正确的设置allowScriptAccess的值”always | sameDomain | never”即可。
2,ExternalInterface.addCallBack失效问题:
其实老实说,如果老老实实的放个flash在页面上,一般调用flash注册的方法是不会出什么问题的。但是世界上没有“老老实实”这么一说,而很多addCallBack的问题都是因为flash元件被隐藏导致的。
2.1 swf与页面文件不同域,flash的Security.allowDomain限制导致报错
不同域的情况下,js调用flash注册的外部方法也会报错,典型的报错信息为”Error Calling Method on NPObject”(大概是这样,关键字是NPobject)。
解决办法:在flash的初始化时设置Security.allowDomain,没有特殊要求的情况下可以直接写Security.allowDomain(“*”)。另外值得注意的是flash不支持多级域名的匹配。例如a.qzone.qq.com和b.qq.com,就不能统一用Security.allowDomain(“*.qq.com”)来匹配,而是要老老实实的写Security.allowDomain(“*.qq.com”,”*.qzone.qq.com”);
2.2 flash被display:none;visibility:hidden,移出页面可视区域外,导致绑定方法失效。
具体的报错信息为调用时会说没有对应的函数。特别注意一下在一些“标准浏览器”(Firefox,Chrome…)下,flash隐藏再出现,会销毁原来的flash,当flash重新显示时再创建一个新的实例。这就导致一些原先保存在Flash中的FileReference句柄被干掉,甚至一些其他未知的问题。所以比较安全的做法还是把flash的width和height都设置为1px(当然这个需要css的大力配合)。
解决办法:不要使用传统的flashObj.funcName()方式调用。而是在调用前强制把addCallBack的实际代码再运行一次。
- /**
- * 用js的callFunction方法替代传统的flashObj.funcName()
- * flashObj flash对象
- * funcName flash注册的函数名
- */
- function callFunction(flashobj,funcName) {
- Array.prototype.splice.call(arguments,0,2)
- var returnString = flashobj.CallFunction([
- '',
- __flash__argumentsToXML(arguments, 0),
- ''
- ].join(''));
- var returnValue = eval(returnString);
- if (returnValue != undefined && typeof returnValue.post === "object") {
- returnValue = unescapeFilePostParams(returnValue);
- }
- return returnValue;
- };
- function unescapeFilePostParams(file) {
- var reg = /[$]([0-9a-f]...{4})/i;
- var unescapedPost = {};
- var uk;
- if (file != undefined) {
- for (var k in file.post) {
- if (file.post.hasOwnProperty(k)) {
- uk = k;
- var match;
- while ((match = reg.exec(uk)) !== null) {
- ukuk = uk.replace(match[0], String.fromCharCode(parseInt("0x"+match[1], 16)));
- }
- unescapedPost[uk] = file.post[k];
- }
- }
- file.post = unescapedPost;
- }
- return file;
- };
热门文章推荐
- [HLS]做自己的m3u8点播系统使用HTTP Live Streaming(HLS技术)
- [FMS]FMS流媒体服务器配置与使用相关的介绍
- [AS3]什么是M3U8,与HTML5的区别是什么
- AS2.0 让flash自适应全屏,并且不自动缩放
- [AS3]as3.0的sound类常用技巧整理
- [AS3]as3与ByteArray详解、ByteArray介绍、ByteArray用法
- 关于RTMP,RTMPT,RTMPS,RTMPE,RTMPTE协议的介绍
- [JS]分享浏览器弹出窗口不被拦截JS示例