1

我正在使用来自 Mozilla 的经典 OOP 代码

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);

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

4

2 回答 2

1

几个选项:

使用Function#bind

我相信在 Firefox 扩展中,如果不是所有 ES5 功能,您应该拥有大部分可用的功能,这意味着您可以使用它Function#bind来确保您的事件处理程序被调用并this设置为您的实例。例如:

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

在对 的调用中onPageLoadthis将引用您的实例。您将无法访问普通thisFirefox 提供的事件处理程序(选项卡或其他)。

选项的更完整示例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);
}

(如果“闭包”对您来说是一个新术语,请不要担心,闭包并不复杂。)

关闭选项的完整示例:

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);
于 2012-01-06T15:06:02.897 回答
0

你可能对使用“this”有点犹豫。将您的全局变量属性设为 MyExtension 并通过变量的全名而不是使用可能不明确的“this”来引用变量。例如:

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';
   }

};

于 2013-05-21T12:32:36.547 回答