·您当前的位置:首页 > 技术教程 > AS2与AS3技术 >

[AS3]as3中保证ExternalInterface的可用性的四个方法

时间:2012-07-24 09:15DannyCheung
[AS3]as3中保证ExternalInterface的可用性的四个方法,很多flash和js同学在页面接入flash的时候,都会碰到调用flash注册给外部的方法失败的问题。现在总结几种情况

  很多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的实际代码再运行一次。
 

  1. /**  
  2. * 用js的callFunction方法替代传统的flashObj.funcName()  
  3. * flashObj flash对象  
  4. * funcName flash注册的函数名  
  5. */  
  6. function callFunction(flashobj,funcName) {  
  7. Array.prototype.splice.call(arguments,0,2)  
  8. var returnString = flashobj.CallFunction([  
  9. '',  
  10. __flash__argumentsToXML(arguments, 0),  
  11. ''  
  12. ].join(''));  
  13. var returnValue = eval(returnString);  
  14. if (returnValue != undefined && typeof returnValue.post === "object") {  
  15. returnValue = unescapeFilePostParams(returnValue);  
  16. }  
  17. return returnValue;  
  18. };  
  19.  
  20. function unescapeFilePostParams(file) {  
  21. var reg = /[$]([0-9a-f]...{4})/i;  
  22. var unescapedPost = {};  
  23. var uk;  
  24.  
  25. if (file != undefined) {  
  26. for (var k in file.post) {  
  27. if (file.post.hasOwnProperty(k)) {  
  28. uk = k;  
  29. var match;  
  30. while ((match = reg.exec(uk)) !== null) {  
  31. ukuk = uk.replace(match[0], String.fromCharCode(parseInt("0x"+match[1], 16)));  
  32. }  
  33. unescapedPost[uk] = file.post[k];  
  34. }  
  35. }  
  36. file.post = unescapedPost;  
  37. }  
  38. return file;  
  39. }; 

 

热门文章推荐

请稍候...

保利威视云平台-轻松实现点播直播视频应用

酷播云数据统计分析跨平台播放器