在firefox扩展中使用OOP

时间:2012-01-06 14:59:46

标签: javascript firefox firefox-addon xpi

我正在使用classic OOP code from Mozilla

var myExtension = {
    init: function() {
        // The event can be DOMContentLoaded, pageshow, pagehide, <b style="color:black;background-color:#99ff99">load</b> or unload.
        if(gBrowser) gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
    },
    onPageLoad: function(aEvent) {
        var doc = aEvent.originalTarget; // doc is document that triggered the event
        var win = doc.defaultView; // win is the window for the doc
          alert("<b style="color:black;background-color:#a0ffff">page</b> is loaded \n" +doc.location.href);
        //OOPs, error here, username is undefined
        Firefox.Console.log(this.userName);
    },
    anotherMethod: function (){
       this.userName = 'UserName'; 
    }
}
window.addEventListener("<b style="color:black;background-color:#99ff99">load</b>", function() { myExtension.init(); }, false);

一般问题是如何在我的课程中初始化和使用公共变量? 你知道,这个类中的这个是一些浏览器的对象(tab),但不是当前的一个类,我不能分配this.win = doc.defaultView并且稍后使用this.win.userName = 'UserName'

2 个答案:

答案 0 :(得分:1)

有两种选择:

使用Function#bind

我相信在Firefox扩展程序中,您应该拥有最多(如果不是所有)ES5功能,这意味着您可以使用Function#bind确保调用事件处理程序并将this设置为您的实例。 E.g:

if (gBrowser) {
    gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad.bind(this), false);
}

onPageLoad的来电中,this会引用您的实例。您无法访问正常的this Firefox提供事件处理程序(标签或其他)。

bind选项的富勒示例:

var myExtension = {
    init: function() {
        // The event can be DOMContentLoaded, pageshow, pagehide, <b style="color:black;background-color:#99ff99">load</b> or unload.
        if(gBrowser) {
            gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad.bind(this), false);
        }
    },
    onPageLoad: function(aEvent) {
        var doc = aEvent.originalTarget; // doc is document that triggered the event
        var win = doc.defaultView; // win is the window for the doc
          alert("<b style="color:black;background-color:#a0ffff">page</b> is loaded \n" +doc.location.href);
        // This now works
        Firefox.Console.log(this.userName);
        // ...but you don't have access to the `this` that the browser gave
        // the event handler (the tab or whatever)
    },
    anotherMethod: function (){
       this.userName = 'UserName'; 
    }
}
window.addEventListener("<b style="color:black;background-color:#99ff99">load</b>", function() { myExtension.init(); }, false);

使用闭包:

如果我在Firefox扩展中误认为ES5,或者如果您想要访问事件处理程序通常会收到的this,您可以使用闭包来执行相同的操作:

var self = this;
if (gBrowser) {
    gBrowser.addEventListener("DOMContentLoaded", function(event) {
        // Here, `self` refers to your instance, and `this` to the
        // element, so for instance you can call your `onPageLoad`
        // and pass it the element as a second argument:
        return self.onPageLoad(event, this);
        // Within the call to `onPageLoad`, `this` will be your instance
    }, false);
}

(如果&#34;关闭&#34;对你来说是一个新名词,请不要担心,closures are not complicated。)

关闭选项的富勒示例:

var myExtension = {
    init: function() {
        var self = this;

        // The event can be DOMContentLoaded, pageshow, pagehide, <b style="color:black;background-color:#99ff99">load</b> or unload.
        if(gBrowser) {
            gBrowser.addEventListener("DOMContentLoaded", function(event) {
                return self.onPageLoad(event, this);
            }, false);
        }
    },
    onPageLoad: function(aEvent, aElement) {
        var doc = aEvent.originalTarget; // doc is document that triggered the event
        var win = doc.defaultView; // win is the window for the doc
          alert("<b style="color:black;background-color:#a0ffff">page</b> is loaded \n" +doc.location.href);
        // This now works
        Firefox.Console.log(this.userName);

        // If you needed the `this` that Firefox gives the event handler
        // (the tab or whatever), it's accessible via `aElement`
    },
    anotherMethod: function (){
       this.userName = 'UserName'; 
    }
}
window.addEventListener("<b style="color:black;background-color:#99ff99">load</b>", function() { myExtension.init(); }, false);

答案 1 :(得分:0)

使用&#34;这可能会让你有点过分。&#34;制作MyExtension的全局变量属性,并按其全名引用变量,而不是使用&#34; this,&#34;这可能是模棱两可的。例如:

var myExtension = {
    username : '',
    email : '',

    init : function() {
        if ((app = document.getElementById("appcontent"))) {
            app.addEventListener("DOMContentLoaded", myExtension.run, true);
        }
   },

   run : function(event) {
       ...
    },

   anotherMethod : function() {
       // same as your example: this.username = 'Username';
       myExtension.username = 'Username';
   }

};