在Javascript中监听flash事件

在Javascript中监听flash事件,其实有两种做法:

1、在特定的环境下(例如专门制作的flash),大家约定一个全局函数,然后在flash的事件中用ExternalInterface.call调用这个全局函数即可。
2、在非特定的环境下(例如编写通用的flash插件),是不能限制用户的函数名的,所以根本无法约定全局函数;是否可以通过类似js的回调函数的形式实现事件监听呢?

其实js与flash的通信,一般情况下可以进行一些比较简单的通信,如传递基本的数据类型、传递简单的对象、调用函数等,可是Function(即函数,回调函数肯定都是Function类的实例)不在基本的数据类型中,它是无法被传递的。

虽然不知道还有没其他的方法可以进行传递,但至少在我自己的实验中还没办法实现。

所以,如果是第二种情况的话,一般来说比较简单的方式就是先在flash中实现一个api,通过这个api传递某个js的全局函数名称,然后在flash的事件中调用该函数,如:

在flash中输入下面的as代码:

import flash.external.ExternalInterface;

var events:Object = {};
// 注册js可以调用的api
ExternalInterface.addCallback("addEventListener", addEventListener);

function addEventListener(key:String = null, value:String = null):Boolean
{
	if (key == null || value == null) return false;
	switch (key)
	{
		case "complete":
			events.complete = value;
			return true;
		// 用类似的方式添加其他事件
	}
	return false;
}

然后在flash的某个事件中,调用js函数:

import flash.events.Event;
import flash.external.ExternalInterface;

function complete_handler(event:Event):void
{
	if (events.complete != null)
		ExternalInterface.call(events.complete);
		/*
		如果需要传递参数,请用下面这句:
		ExternalInterface.call(events.complete, 参数1, 参数2...);
		*/
}

现在,js可以通过下面的代码监听时间了:

// swf是你的flash object对象,自行获取吧
swf.addEventListener("complete", complete_handler);

function complete_handler()
{
	alert("事件监听成功啦~!");
}

可是,上面的监听方式有个缺点,就是如果事件的参数不是固定的,参数传递会很麻烦。或者在有的情况下我还是希望用回调函数的方式来监听flash事件呢,那么可以在js中做一个事件代理:

var flash = {
	types: {},
	event: function (type)
	{
		var listeners = this.types[type];
		if (listeners)
		{
			for (var i = 0; i < listeners.length; ++i)
			{
				listeners[i]();
			}
		}
	},
	addEventListener: function (type, fn)
	{
		if (!this.types[type])
		{
			this.types[type] = [];
		}
		this.types[type].push(fn);
	}
};

flash.addEventListener("load", load);
flash.addEventListener("complete", function ()
{
	alert("加载完成~!");
});

function load()
{
	alert("正在加载~!");
}

然后在flash事件中调用下面代码:

import flash.events.Event;
import flash.external.ExternalInterface;

function load_handler(event:Event):void
{
	ExternalInterface.call("flash.event", "load");
}

function complete_handler(event:Event):void
{
	ExternalInterface.call("flash.event", "complete");
}

如果谁还有新的方法或思路,欢迎随时指教!

此条目发表在原创空间, 技术随笔分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。

发表评论