読み込んでいます...

在很多时候我们开发Firefox插件,我们都需要一些高级的功能,例如选择国家,我做的一个插件就支持10几个国家,那么用户怎么去改这个国家呢。嗯。有办法,聪明的读者肯定会说,我们新创建一个XUL的窗体,然后在里面设置,修改相应的Pref,然后保存不就可以了吗,嗯,这是个好方法,不过有个前提,这个前提就是你的类要写成静态类,写法就类似于var someclass = { test:function(){}}这样,如果你这样写,可以在不同窗体设置一下变量,因为这个时候overlay是全局的,当然可以,但是如果你要重用代码的话,就会遇到JS的代码冲突和覆盖的问题(具体看这里1这里2),如果出现冲突,那么代码可能就毁了,唯一能做的就是,不重用代码,但是肯定不会这样做啦。

我们可以这样做试试,我们写一个扩展,然后打开“工具-扩展插件”,或者说自己定义一个XUL,然后关闭XUL,那如何主的XUL会知道这个窗体关闭呢?这里就好象你打开两个毫不相关的网页,一个网页关了,另一个网页肯定不会知道这个网页已经关了,因为就算他们引用的是同一个JS,但是创建的类是不同的,而且彼此之间的状态是毫不相关的。不信你可以写写下面的代码。

//定义一个类,并初始化构造函数
Tester = new function(id){this._id=id};

//实现类的内部结构
Tester.prototype =
{
    _id:
null,
    ShowId:
function()
    {
        
return this._id;
    }
}

我们设计了一个类之后,我们可以做两个XUL,或者你做两个HTML也行,然后都调用这个js,然后一个都在load方法里面写var test = new Tester(1),建议一个传递构造参数1,一个传递2,然后你打开2,看看,这个对象是哪个对象?对,是2的对象,而不是1的对象,因为就算他们用了同一个JS,创建的实例也是不同的,实例不同,也无法互相交互,所以关闭2的时候,根本不可能通知消息给1。

这就像给你两个毫不相干的程序,你点了这个程序的按钮,另一个程序执行了一个方法。

不过在Firefox平台下面我们有一个JSM可以完成这个需求,有关JSM(Using JavaScript code modules)可以去链接的位置,不过JSM就像C++里面的#include,并且这个还是在整个浏览器作用域的(两个窗体共享一个对象)。了解了JSM之后,我们就可以编写JSM了,JSM编写起来很简单,我们可以这样写一下。

//这个对象必须要使用,注册JSM
var EXPORTED_SYMBOLS = ["SetObject","GetObject","obj","id"];

//这里和JS写法都一样

var
object;

//设置object
function SetObject(obj)
{
    
object = obj;
}

//获取object
function GetObject()
{
    
if(object)
    {
        
return object;
    }
    
else
    {
        
return "not set";
    }
}

其中EXPORTED_SYMBOLS是必须要写的,注册你申明的所有变量,让Firefox知道这个,下面就和一般JS一样了,我们写完后保存为Global放到content下面的文件夹的lib里面。好了,我们的一个JSM就可以使用了,那么如何使用JSM呢,我们可以在JS里面写这样的代码。

//有点像Include吧
Components.utils.import("resource://{appname}/Global.jsm");

//使用全局的方法,定义一个object以便在其他窗体使用
SetObject(myobject);

当我们需要使用我们的对象的时候,只要在另一个窗体再Include一下,然后使用GetObject方法就能够调用出我们的全局共享的对象了。

不过在这里还并不能开始使用,我们可以看到Components.utils.import这个方法,相当于#include的方法,但是是有规则的,也不能随便写。这个方法的参数是路径,我前面把这个文件放到content/lib下面,这里我们还要写路径。

首先在chrome.manifest里面写这段。

resource {appname}      content/lib/

其中{appname}后面的别名,说简单点就是key=value,{appname}=content/lib/。(最后一个斜线一定要写),由于我用的是NetBeans,所以可以写{appname}最后会被IDE给替换掉,如果是手写的话,这里可以定义为自己的一个名字,不过建议最好还是和项目名称挂钩,免得冲突。

然后再看回我们的调用这个JSM地方代码,是不是就了解了呢?其中resource代表了资源文件,后面代表了我的路径(通过别名访问),最后就是文件名了。只有这样设置,一个可以跨窗体的JS对象就可以互相共享了,这样当我们有一些弹出窗体要更改我们的扩展的时候,就可以使用这种方法实现。

285路过 1评论 Firefox Addon 阅读全文..
  1. 置顶的更新,文章汇总 : GuoJing's Blog | 用心对待每一行代码 @

    [...] Firefox Add-on – JSM跨窗体共享对象 [...]

:-D :-? 8) :cry: 8-O :lol: :-x :-| :?: :-P :oops: :roll: :( :) :-o :wink: more »