読み込んでいます...

在做了Firefox插件这么长时间,还是被Firefox插件的命名空间问题弄的头晕脑胀,如果我们想要代码重用,例如我写个Google搜索栏,然后再写Baidu搜索栏,以为可以良好的运行,其实并不可以,因为无论是id,还是方法都会冲突,更可怕的是命名空间和js文件的冲突。可以说,冲突的问题真是千奇百怪啊。

因为命名空间出错,大部分是因为我们通常情况下编写JavaScript的时候都是以静态的方法去写的,JavaScript其实是面向对象的编程语言,所以如果你不习惯用面向对象开发,那就要好好学习一下JavaScript的面向对象了,OK,多的不说,我们首先要写一个变量。注意,整个全局中都只能有一个共有变量,否则其他的变量很可能引起冲突。

// 只有一个的共有变量
var FFNamespace = {};

// 命名空间
(function() {

var namespaces = [];

// 注册命名空间
this.ns = function(fn) {
    
var ns = {};
    namespaces.push(fn, ns);
    
return ns;
};

// 初始化命名空间
this.initialize = function() {
    
for (var i=0; i<namespaces.length; i+=2) {
        
var fn = namespaces[i];
        
var ns = namespaces[i+1];
        fn.apply(ns);
    }
};

// 清除命名空间
this.shutdown = function() {
    window.removeEventListener(
"load", FFNamespace.initialize, false);
    window.removeEventListener(
"unload", FFNamespace.shutdown, false);
};

// 初始化生命周期
window.addEventListener("load", FFNamespace.initialize, false);
window.addEventListener(
"unload", FFNamespace.shutdown, false);

}).apply(FFNamespace);

上面的代码我们保存为一个文件就可以了,例如保存为gj.Namespace,但是光只有这里的代码还不够,我们还需要创建公共的变量和方法以便可以互相访问。 

FFNamespace.LIB = {

    // 创建公共变量
    getCurrentURI: function() {
        
return window.location.href;
    },

    // 扩展的快捷方式
    appname: FFNamespace,

    // XPCOM
    Cc: Components.classes,
    Ci: Components.interfaces
};

上面的代码我们可以保存为gj.Namespace.Lib,看了上面的代码之后,你肯定不太清楚appname是干什么用的,这里appname就相当于是一个快捷方式。因为如果写命名空间的全称,可能比较长,定义了快捷方式之后我们就可以用快捷方式来命名了。 

现在我们来创建两个“冲突”的js文件,分别为Test1和Test2。 

FFNamespace.ns(function() { with (FFNamespace.LIB)
{
    appname.Test1
=
    {
        onClick:function()
        {
            alert(
test 1 on click);
        }
    }
}});

上面是Test1,下面是Test2。

FFNamespace.ns(function() { with (FFNamespace.LIB)
{
    appname.Test2
=
    {
        onClick:function()
        {
            alert(
test 2 on click);
        }
    }
}});

上面的代码我们同样保存为Test1.js和Test2.js,保存完之后我们就可以写XUL了。XUL代码如下。 

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://{appname}/skin/overlay.css" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://{appname}/locale/overlay.dtd">
<overlay id="{appname}-overlay"
         xmlns
="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    
<script src="chrome://{appname}/content/gj.Namespace.js"
            type
="application/x-javascript"/>
    
<script src="chrome://{appname}/content/gjNamespace.Lib.js"
            type
="application/x-javascript"/>
    
<script src="chrome://{appname}/content/Test1.js"
            type="application/x-javascript"/>
    
<script src="chrome://{appname}/content/Test2.js"
            type="application/x-javascript"/>
  
  
<!– firefox –>
  
<statusbar id="status-bar">
        
<statusbarpanel id="bar1" onmousedown="FFNamespace.Test1.onClick();">
            
<label value="My God!"/>
        
</statusbarpanel>
  
</statusbar>

</overlay>

上面我们创建了一个状态栏的插件,让他显示My God!,然后我们执行了命名空间的相应的方法,这里我们可以看到两个代码基本上都是差不多的,而且我们就算把这个插件换一个名字,再同样安装,也是没有任何冲突的,怎么样,是不是完美的解决方法? 

其实这个原理说简单也简单,说复杂也复杂,主要是把命名空间对象放到数组里面,这样就能够减少冲突了。还可以参考这篇文章

336路过 2评论 Firefox Addon 阅读全文..
  1. DiamRem @

    本来还想问你这个代码引用是怎么弄的
    结果发现用的不是一个博客系统……

    主题一样而已,汗……

  2. 置顶的更新,文章汇总 : GuoJing's Blog | 用心对待每一行代码 @

    [...] Firefox Add-on – 完美解决命名空间问题 [...]

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