[转帖]Mootools源码分析-27 -- Swiff

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-404749

原作者:我佛山人

 

/*
    SWFObject的流行,得益于微软在IE中加了控件激活设置(目前已经去掉限制)
    而通过调用外部脚本生成插入Flash的HTML,却能避开激活限制。
    通过使用SWFObject,插入Flash已经变得很简单
    而moo的Swiff的创意来自SWFObject,正如moo来源于Prototype
    通过Swiff类,可以学到封装UI组件,需要提供的基本方法:
    1.事件支持(本例使用callback而不是Events的实现,一般情况下使用Events类的接口实现)
    2.配置可选项(Options类setOptions的接口实现)
    3.将组件添加到DOM中的方法
    4.提供UI组件中重要HTML Element的引用
    至于如何使用Swiff类,可以看moo的官方Swiff教程
*/
var Swiff = new Class({
    
//setOptions接口实现,因为本类的特殊性,没有使用Events的事件接口实现
    Implements: [Options],
    options: {
        id: 
null,                 //生成object/embed的id
        height: 1,                 //高度
        width: 1,                 //宽度
        container: null,         //容器
        properties: {},         //属性集
        params: {                 //参数集
            quality: 'high',        //播放质量
            allowscrīptAccess: 'always',
            wMode: 
'transparent',    //透明模式
            swLiveConnect: true        //是否启动Java,以支持fscommand
        },
        callBacks: {},             
//回调方法集
        vars: {}                 //变量集
    },

    
//获取指向的HTML Element对象
    toElement: function()    {
        
return this.object;
    },

    
/*
    path为swf文件路径
    
*/
    initialize: 
function(path, options)    {
        
//生成唯一实例名
        this.instance = 'Swiff_' + $time();
        
this.setOptions(options);
        options 
= this.options;
        
//得到唯一id
        var id = this.id = options.id || this.instance;
        
//容器
        var container = $(options.container);
        
//使用唯一实例名初始化当前对象的回调方法集
        Swiff.CallBacks[this.instance] = {};
        
var params = options.params, vars = options.vars, callBacks = options.callBacks;
        
var properties = $extend({height: options.height, width: options.width}, options.properties);
        
//声明局部变量,用于下面的闭包中的引用
        var self = this;
        
//复制回调方法
        for (var callBack in callBacks)    {
            Swiff.CallBacks[
this.instance][callBack] = (function(option)    {
                
return function()    {
                    
return option.apply(self.object, arguments);
                };
            })(callBacks[callBack]);
            
//最终通过flashVars参数传给swf
            vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack;
        }
        params.flashVars 
= Hash.toQueryString(vars);
        
//IE使用classid,其它浏览器声明contentType,注意文件路径对应的属性
        if (Browser.Engine.trident)    {
            properties.classid 
= 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
            params.movie 
= path;
        }    
else    {
        properties.type 
= 'application/x-shockwave-flash';
        properties.data 
= path;
        }
        
/*
        字符串拼接出最终输出的HTML代码
        如果要考虑效率,这里应该用数组,否则使用字符串的substitute方法会更优雅
        
*/
        
var build = '<object id="' + id + '"';
        
//遍历拼接属性
        for (var property in properties)    build += ' ' + property + '="' + properties[property] + '"';
        build 
+= '>';
        
//遍历拼接参数
        for (var param in params)    {
            
if (params[param])    build += '<param name="' + param + '" value="' + params[param] + '" />';
        }
        build 
+= '</object>';
        
//因为属性和参数太多,如果直接new Element的话会比较烦琐,所以直接new一个临时的div,设置其HTML再返回子节点
        this.object =  ((container) ? container.empty() : new Element('div')).set('html', build).firstChild;
    },

    
//将当前对象替换element,也许是为了避免模块间藕合太过,所以没有直接使用Element的replaces方法
    replaces: function(element)    {
        element 
= $(element, true);
        element.parentNode.replaceChild(
this.toElement(), element);
        
return this;
    },

    
//附加到element中,这里也没有直接使用Element的inject方法
    inject: function(element)    {
        $(element, 
true).appendChild(this.toElement());
        
return this;
    },

    
//方法调用
    remote: function()    {
        
return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments));
    }
});

//回调方法集
Swiff.CallBacks = {};

//swf到js的方法调用
Swiff.remote = function(obj, fn)    {
    
var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascrīpt">' + __flash__argumentsToXML(arguments, 2+ '</invoke>');
    
return eval(rs);
};

 

posted @ 2009-11-24 14:59  webgis松鼠  阅读(355)  评论(0编辑  收藏  举报