羽翼飞扬

古人学问无遗力,少壮工夫老始成。纸上得来终觉浅,绝知此事要躬行。

导航

JS 与 AS交互的一些事情

  说来话长了,记得2002年的第一场雪。余下省略5000字...

  说归说,笑归笑,咱们言归正传啊。关于JS于AS交互的文章网上也是一搜罗一大把的。在这呢,我就是想写一点我遇到的问题。哎呀,可折腾了我不少时间啊。 近日由于工作需求 ,需要和一名AS同事负责进行交互,网上也瞅了瞅,看了些文章,觉得好弄。挺简单的。然后卷起袖子准备大干一场!不巧就遇上了绊子。

   

  1.(Flash 文件访问跨域)

    首先的请求跨域的问题。如果flash文件要请求一段地址的话。会先请求其服务器根目录下是否存在 crossdomain.xml 文件,然后对其XML格式内容进行解析。如果确实对你的请求授予权限了。那就OK,结果就理所当然响应给你。不然就整个XML 跨域文件放到服务器根目录下就行。flash在跨域时唯一的限制策略就是crossdomain.xml文件,该文件限制了flash是否可以跨域读写数据以及允许从什么地方跨域读写数据。若不存在主策略文件,则该域将禁止任何第三方域的flash跨域请求。一般格式如下:

  <cross-domain-policy>

       <allow-access-from domain="*" /> 

  </cross-domain-policy>

      domain该属性指定一个确切的 IP 地址、一个确切的域或一个通配符域(任何域)。只有domain中指定的域,才有权限通过flash读取本域中的内容。

一般情况下还是设置比较信任的域才能访问自身服务器,如果写成通配符"*"的话,是极不安全的。

 

  2.(Javascript 脚本限制)

  没什么说的,如果该属性不写的话,会提示安全沙箱的错误。意指执行JS脚本受限,未授予访问权限。

  在 <object> 标签之内添加:<param value="always" name="allowScriptAccess">还没完,接着还要在 <embed> 标签写上 allowScriptAccess="always" 为了兼容IE和其他W3C标准浏览器。 基本上JS脚本受限制的问题就解决了。。

 

 3.(关于 ActionScript 脚本执行 Externalinterface.addCallback() 的时机)

    有时候,大家可能会遇到当在HTML页面中插入一段FLASH文件,然后进行JS交互时,会有AS函数调取不到('xxx' not is a function)的问题存在。如果当页面DOM数量少,且请求文件少和带宽占用少的页面进行交互,大概不会出现这种问题。一般情况下 addCallback 执行的最好时机就是当页面完全加载好时,onload complete(注意:这里的加载完成不是指DOM树构造完毕,而是说页面中所有请求的资源:图片、flash等等的加载完毕).再用AS去执行 addCallback 注册的函数,就不会发生这种 AS 函数不存在的问题了。至于怎么去判定和准时注册AS函数,我觉得是可以这么去做。

首先JS代码如下:

 

var jsReady = false;

window.onload = function(){ jsReady = true; }

function pageIsReady() {
  return jsReady;

}

 

然后ActionScript那边生成一个定时器,隔上500ms 或 1000ms 执行一次该函数。(时间长短可由个人需要指定),如果返回值为真,说明页面已经加载完毕了。此时将需要注册的函数Externalinterface.addCallback() 一并写入,并解除定时器,就行了!一般情况下来说,解决AS调取不到的问题是可以了。

 

  4.(关于ActionScipt 调用JS函数一个比较容易忽略的问题)

    有时大家可能有将 FLASH文件 嵌入在一个 iframe 子框架中,但是这个flash文件又需要调用到外部的JS函数。可能就直接 call(FuncName) 的调用了。结果出错。JS函数未找到、未定义。

  很苦恼,很费解,很压抑,觉得生活不能自理了。呵呵,我的想法就是。在FLASH文件嵌入的当前 窗体对象中。写入一段javascript代码。也可以是动态创建添加都行。不过我这边IE浏览器好像有点问题,通过如下形式:

var scriptEl = document.createElement('script');

scriptEl.type = 'text/javascript';

scriptEl.innerHTML = 'function mutualCallback( f ) { typeof window.top[f] === 'function' && window.top[f](); }';

(iframe.contentWindow.document || iframe.contentDocument).getElementsByTagName('head')[0].appendChild(scriptEl);

 

没有成功,会报错。。很是郁闷。然后无奈之下将该代码放入外部文件引入才罢休。

好了,就如以上形式就可以实现AS 调用 JS 不在一个frame框架环境的问题了。当然每个人有每个人的需求。再作相应修改和处理便是。

 

  5.(最后一个也就是 JS调用AS函数)

  关于JS调用AS,网上罗列了不少方法,形形色色大同小异。

  首先 将<object>标签的ID属性和<embed>标签的NAME属性 设为一样即可。chrome, ff, ie ... 获取形式各异。

  IE 是通过 Active控件 来加载flash, 且仅仅支持<object>标签,<embed>标签留与不留没有影响的。

  其它标准浏览器就是 通过 <embed> 标签来解析flash了。

  具体获取方法:

 

function getFlashObject( id ) {

if (navigator.appName.indexOf("Microsoft Internet") == -1) {  

    if (document.embeds && document.embeds[id]){  

        if(navigator.userAgent.indexOf("Firefox")>0){  

            return document.embeds[id];  

        }else{  

            return window[id];  

        }  

    }  

    else{  

        return window.document[id];  

    } 

  }  

  else {                    

    return window[id];

  }

 }

 

 

  然后将object的id 或者 embed的name,传进来即可。然后就返回的标签对象 比如:getFlashObject('flashObj')['callAS']();即可。callAS 是AS那边注册的函数名称!

 

这里需要注意一个问题就是。IE 浏览器当中,如果你添加了很多个 FLASH 对象,且ID值一样,方法会出现在第一个对象身上。比如页面中有10个flash对象。ID="myflash"然后每个flash对象 有不同的

Externalinterface.addCallback() 注册的函数,这时候调用 getFlashObject('myflash'),会返回10个Object元素。那么你想遍历该DOM集合,然后依次调用该flash对象注册的函数。那么结果会

让你百思不得其解的。。只有第一个object元素 能获取到注册的函数,往后的都是空。然后还有一种情况:

页面中有10个flash对象,然后只有一个flash有注册函数。但是问题是10个flash是无序且打乱的插入在你的页面当中的。你并不能具体指定到哪个flash对象,然后只能将10个都给获取。然后通过

判断检查元素是否有某个注册函数,如果有就调用。那么结果也是不一样的。比如现在是第5个flash对象是有注册函数的:名称是 callAS. 然后你通过window[id]获取到当前所有的 flash 集合。

并检测属性是否为函数,那么会返回第一个元素也就是 window[id][0] 有['callAS'] 属性且类型为函数。 但调用时出错。因为该flash并没有该注册的函数。所以肯定失败。 由此看来。在IE当中。

若想JS 调用 AS函数成功,还是要指名道姓,指定一个元素然后来调用注册函数。

 

本文属于原创,希望各位多批评指正!

- 羽翼飞扬

 

posted on 2013-12-03 00:24  羽翼飞扬  阅读(567)  评论(0编辑  收藏  举报