【问题标题】:Using OOP in firefox extension在 Firefox 扩展中使用 OOP
【发布时间】:2012-01-06 14:59:45
【问题描述】:

我正在使用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);

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

【问题讨论】:

    标签: javascript firefox firefox-addon xpi


    【解决方案1】:

    几个选项:

    使用Function#bind:

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

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

    (如果“闭包”对你来说是个新名词,别担心,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);
    

    【讨论】:

    • 谢谢,我会尝试,但我在那里使用 jQuery,它可能会受到影响,因为 jQuery 也有绑定实现。
    • @Castro:没有冲突,jQuery 的jQuery.proxy 与Function#bind 没有冲突。 jQuery 只保留 JavaScript 内置对象。但如果您愿意,可以使用jQuery.proxy:..., jQuery.proxy(this.onPageLoad, this), ...
    【解决方案2】:

    您可能对使用“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';
       }
    

    };

    【讨论】:

      猜你喜欢
      • 2011-03-10
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多