我使用的是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.win = doc.defaultView
,以后也不能像this.win.userName = 'UserName'
那样使用
几个选项:
使用Function#bind
:
我相信,在Firefox扩展中,即使不是所有ES5功能,也应该拥有大部分功能,这意味着你可以使用Function#bind
来确保在this
设置为你的实例的情况下调用你的事件处理程序。例如:
if (gBrowser) {
gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad.bind(this), false);
}
在对onPageLoad
的调用中,this
将引用您的实例。您将无法访问Firefox提供给事件处理程序的普通this
(选项卡或其他什么)。
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);
使用"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';
}
};