文章都是发布在github再转到这边的,这边格式可能会乱掉.博客地址:benqy.com

写在前面的废话

公司首页的flash广告,都是由第三方制作的,脚本和flash文件都是由各个广告公司独立制作,然后在我们页面引用.这样的方式肯定不靠谱,页面脚本非常的乱,因此现在想收回脚本控制权,采用的方式是要求广告公司做出的flash素材要按要求实现接口供js调用,并且实现类似事件的机制,在广告的各个状态切换时通知页面脚本.

以前都没接触过flash,现在只好临阵磨枪,挑一些会用到的学习一下,顺便记下来.

这篇主要讲讲js和as3之间如何交互,如何实现简单的类似事件的机制.

模拟事件

在as3中,无论是调用js的方法,还是暴露接口给js,都是用ExternalInterface这个api.
暴露接口:ExternalInterface.addCallback(函数名, 函数)
调用js方法:ExternalInterface.call(方法名, 参数)

这里所说的模拟事件,就是在falsh素材的各个状态切换时,通知页面.如加载完毕时,触发onload事件,播放时触发onplay,停止时触发onstop等等.

采用的方案,是在object标签里,添加自定义的属性供as3调用,属性名是flash定死的:flashvars,值的格式类似url里的参数部分,为用&分隔的键值对,如下:

在as3中,这样读取属性:

  1. flashvars= LoaderInfo( this.root.loaderInfo ).parameters;

flashvars是一个object变量,定义如下:

  1. private var flashvars:Object;

读取后,flashvars的值:

  1. Object {onload: "advnr70wyu5xncanvpwzzo0pory66", onplay: "advf4q8r99cfnryhn2tk2n3s48kf0", onstop: "adv7sgjk0529cd00q6ojuf537"}

对象的key为事件名,值为事件处理函数名,所有事件处理函数都在window.flashCallback命名空间下,并且名字是随机生成的不可重复的guid.

在as3里,我们判断是否支持调用js函数:

  1. ExternalInterface.available

以onload事件为例,在素材加载完毕后,如果支持调用js函数,则触发onload事件:

  1. //素材加载完毕,调用onload
  2. private function onload():void {
  3. if (ExternalInterface.available) {
  4. textField.text = 'onload';
  5. if(flashvars.onload){
  6. ExternalInterface.call("window.flashCallback." + flashvars.onload);
  7. }
  8. }
  9. }

上面提到,函数名是随机生成的,类似jquery的$.ajax方法里的callback实现方式,以下是封装过的生成object标签的方法:

  1. //adv.flash.embed是封装过的生成object标签的方法
  2. asyncTest('flash标签自定义事件', function () {
  3. expect(3);
  4. document.body.appendChild(adv.flash.embed({
  5. id: 'flashGetSWF',
  6. source: 'test.swf',
  7. params: {
  8. onload: function () {
  9. this.play();
  10. ok(true);
  11. },
  12. onplay: function () {
  13. ok(true);
  14. this.stop();
  15. },
  16. onstop: function () {
  17. ok(true);
  18. start();
  19. }
  20. }
  21. }));
  22. });

几个回调函数都是匿名函数,在生成标签之前,会给函数在window.flashCallback下分配一个随机名称.现在只是简单的实现单个事件处理函数的绑定,如果有需要支持多个,只要再做一些简单的封装即可.

adv.flash.embed的实现要点:

  1. //遍历自定义参数
  2. adv.util.forEach(params, function (value, key) {
  3. var funcVar = value;
  4. if (adv.util.isFunction(value)) {
  5. //如果是函数,则生成一个随机的名称,并存储在flashCallback命名空间下
  6. funcVar = adv.util.guid();
  7. window.flashCallback[funcVar] = function() {
  8. var swfObj = adv.flash.getSWF(id);
  9. //this指向flash对象本身
  10. value.apply(swfObj, arguments);
  11. };
  12. }
  13. paramArr.push(key + '=' + funcVar);
  14. });

执行结果:

暴露接口给js

as3里,实现这个很简单,先上代码再说:

  1. public function test() {
  2. flashvars= LoaderInfo( this.root.loaderInfo ).parameters;
  3. //此为调试用
  4. ExternalInterface.call("window.flashCallback.trace",flashvars);
  5. //加载素材
  6. textField.width=200;
  7. textField.height = 90;
  8. addChild(textField);
  9. //素材加载完毕,准备播放
  10. //暴露api给js
  11. if(ExternalInterface.available){
  12. ExternalInterface.addCallback("play", play);
  13. ExternalInterface.addCallback("stop", stop);
  14. }
  15. //触发onload
  16. onload();
  17. }
  18. //这个方法被调用时,开始播放
  19. private function play():Boolean {
  20. textField.text = 'play';
  21. if(flashvars.onplay){
  22. ExternalInterface.call("window.flashCallback." + flashvars.onplay);
  23. }
  24. return true;
  25. }
  26. //这个方法被调用时,停止播放
  27. private function stop():Boolean {
  28. textField.text = 'stop';
  29. if(flashvars.onstop){
  30. ExternalInterface.call("window.flashCallback." + flashvars.onstop,flashvars);
  31. }
  32. return true;
  33. }

这里定义了两个方法,play和stop,在构造函数(test)里,判断ExternalInterface是否可用,如果可用,就暴露出这两个方法:

  1. ExternalInterface.addCallback("play", play);
  2. ExternalInterface.addCallback("stop", stop);

在js里调用:

跨浏览器的获取flash对象引用方法

  1. ...
  2. getSWF:function(name) {
  3. if (navigator.appName.indexOf("Microsoft") != -1) {
  4. return window[name];
  5. } else {
  6. return document[name];
  7. }
  8. }
  9. ...

暴露出的as3方法,会直接附加在object对象上,要注意的是,我们要等onload之后才去调用,保证falsh加载完毕:

  1. asyncTest('js调用flash方法', function () {
  2. expect(1);
  3. document.body.appendChild(adv.flash.embed({
  4. id: 'flashcallSWF',
  5. source: 'test.swf',
  6. width: 300,
  7. height: 190,
  8. params: {
  9. onload: function () {
  10. var result = this.play();
  11. ok(result);
  12. start();
  13. }
  14. }
  15. }));
  16. });

事件函数的this指向flash对象,所以这里不用再获取了

执行结果:

完整的as3代码:

  1. package {
  2. import flash.display.LoaderInfo;
  3. import flash.display.Sprite;
  4. import flash.external.ExternalInterface;
  5. import flash.text.TextField;
  6. public class test extends Sprite {
  7. private var flashvars:Object;
  8. //用textField文本的改变来代表广告播放的状态转变
  9. private var textField:TextField = new TextField();
  10. public function test() {
  11. flashvars= LoaderInfo( this.root.loaderInfo ).parameters;
  12. //加载素材
  13. textField.width=200;
  14. textField.height = 90;
  15. addChild(textField);
  16. //素材加载完毕,准备播放
  17. //暴露api给js
  18. if(ExternalInterface.available){
  19. ExternalInterface.addCallback("play", play);
  20. ExternalInterface.addCallback("stop", stop);
  21. }
  22. //触发onload
  23. onload();
  24. }
  25. //这个方法被调用时,开始播放
  26. private function play():Boolean {
  27. textField.text = 'play';
  28. if(flashvars.onplay){
  29. ExternalInterface.call("window.flashCallback." + flashvars.onplay);
  30. }
  31. return true;
  32. }
  33. //这个方法被调用时,停止播放
  34. private function stop():Boolean {
  35. textField.text = 'stop';
  36. if(flashvars.onstop){
  37. ExternalInterface.call("window.flashCallback." + flashvars.onstop,flashvars);
  38. }
  39. return true;
  40. }
  41. private function onload():void {
  42. if (ExternalInterface.available) {
  43. textField.text = 'onload';
  44. if(flashvars.onload){
  45. ExternalInterface.call("window.flashCallback." + flashvars.onload);
  46. }
  47. }
  48. }
  49. }
  50. }

javascript与as3交互的更多相关文章

  1. iOS中JavaScript和OC交互

    转载自:http://www.devzeng.com/blog/ios-uiwebview-interaction-with-javascript.html 还可参考的文章:http://blog.c ...

  2. jQuery基础与JavaScript与CSS交互-第五章

    目录 JavaScript框架种类及其优缺点 jQuery库 jQuery对象$ 掌握基本选择器 掌握过滤选择器 掌握表单选择器 RIA技术 常见的RIA技术 Ajax Sliverlight Fle ...

  3. 在android中实现webview与javascript之间的交互(转)

    参见“在android中实现webview与javascript之间的交互”

  4. Hybrid App: 对比UIWebView和WebKit实现JavaScript与Native交互

    一.简介 在前面一篇文章中讲到过实现JavaScript与Native交互的方式有一种就是使用原生内嵌webView.在iOS8之前,开发者只能使用苹果提供的UIWebView类来加载URL或者HTM ...

  5. Qt和JavaScript使用QWebChannel交互一——和Qt内嵌网页交互

    Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 目录 Qt和JavaScript使用QWebChannel交互一--和Qt内嵌网页交互 前言 一.效果 二.实现过程 ...

  6. iOS中JavaScript和OC交互 --by 胡 xu

    在iOS开发中很多时候我们会和UIWebView打交道,目前国内的很多应用都采用了UIWebView的混合编程技术,最常见的是微信公众号的内容页面.前段时间在做微信公众平台相关的开发,发现很多应用场景 ...

  7. Duilib嵌入CEF以及JavaScript与C++交互

    转载:http://blog.csdn.net/foruok/article/details/50573612 转载:http://blog.csdn.net/foruok/article/detai ...

  8. iOS UIWebView中javascript与Objective-C交互、获取摄像头

    UIWebView是iOS开发中常用的一个视图控件,多数情况下,它被用来显示HTML格式的内容. 支持的文档格式 除了HTML以外,UIWebView还支持iWork, Office等文档格式: Ex ...

  9. 【iOS开发】UIWebView与JavaScript(JS) 回调交互

    ------------------------------------------------- 很多关于objc 与 js 交互的文章都比较适用于 mac开发,iOS的webview 还是有所不一 ...

随机推荐

  1. Switch能否用string做参数

    在Java5以前,switch(expr)中,exper只能是byte,short,char,int类型(或其包装类)的常量表达式. 从Java5开始,java中引入了枚举类型,即enum类型. 从J ...

  2. Weblogic 监控工具汇总及简介

    https://blog.csdn.net/hualusiyu/article/details/39608637

  3. ORA-01940: cannot drop a user that is currently connected

    https://www.cnblogs.com/lwlxqlccc/p/8694696.html

  4. 什么是web前端,全栈工程师就业前景怎么样?

    Web全栈工程师 什么是web前端? Web为你在浏览器.APP.应用程序等设备上提供直观界面,这些界面展现以及用户交互就是前端. 从2016年到2017年,web前端岗位从之前的爆发式增长变为平稳的 ...

  5. 请教一下16aspx上的源代码要如何在自己的服务器上运行

    很正常呀,,我下载的也有运行不成功的你要去他们16aspx论坛发帖子问这里很少有人回答你这样的问题

  6. (4)PHP基本语法、变量、数据类型、运算符、流程控制

    一.基本语法 1.PHP在网页里的结构 <?php ..... ?> 2.php的另一种格式(不推荐使用) <script language="php"> ...

  7. Python的程序结构[1] -> 方法/Method[1] -> 静态方法、类方法和属性方法

    静态方法.类方法和属性方法 在 Python 中有三种常用的方法装饰器,可以使普通的类实例方法变成带有特殊功能的方法,分别是静态方法.类方法和属性方法. 静态方法 / Static Method 在 ...

  8. 浅析Oracle PL/SQL 学习--未完待续

    这是一篇关于Oracle Pl/SQL数据库编程的课程学习分享... 首先说明几点: 学习这门课程之前,已经学过并且掌握一些基础的SQL语句.数据库结构分析.ER图设计等知识: 这里也只是较为大概地将 ...

  9. 【微信】微信小程序 微信开发工具中新创建的json文件,编译报错VM1781:2 pages/module/module.json 文件解析错误 SyntaxError: Unexpected end of JSON input

    如果新创建报错:编译报错VM1781:2 pages/module/module.json 文件解析错误  SyntaxError: Unexpected end of JSON input 解决方法 ...

  10. 【XStream】xml和java实体的相互转化

    1.pom.xml <!-- xstream xml和Java对象转化 --> <dependency> <groupId>xstream</groupId& ...