Использование ООП в расширении Firefox - PullRequest
1 голос
/ 06 января 2012

Я использую классический код ООП из 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'

Ответы [ 2 ]

1 голос
/ 06 января 2012

Пара вариантов:

Использование 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);

Использование замыкания:

Если я ошибаюсь по поводу ES5 в расширениях Firefox или если вы хотите иметь доступ к 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);
0 голосов
/ 21 мая 2013

Возможно, вы слишком зациклены на использовании "этого". Сделайте ваши глобальные переменные свойствами 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';
   }

};

...