我有一个Javascript对象文字:
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('clearButton').click(function() {
this.trigger('clear'); // doesn't work!
this.Bar.trigger('clear'); // works!
}
}
Toolbar.init($('div.toolbar'));
Toolbar.bind('clear', function() { ... }); // doesn't work!
Toolbar.Bar.bind('clear', function() { ... }); // works!
我希望能够在工具栏对象文字上触发clear
事件,而不是在文字中引用的工具栏DOM对象。这是可能的,如果是的话,我该怎么做?
答案 0 :(得分:1)
这应该有效:
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('.clearButton').click($.proxy(function() {
$(this).trigger('clear'); // should work now
this.Bar.trigger('clear'); // still works
}, this));
}
};
Toolbar.init($('div.toolbar'));
$(Toolbar).bind('clear', function() {
console.log('Toolbar');
}); // should work now
Toolbar.Bar.bind('clear', function() {
console.log('Toolbar.Bar');
}); // still works
您需要在点击功能中维护this
引用。我用$.proxy
;有些人使用var self = this;
Toolbar
不是jQuery对象,因此它应该包含在$()
中以访问jQuery的函数。同时在点击函数中包含引用this
实例的Toolbar
。
答案 1 :(得分:0)
这个怎么样? :
var Toolbar = {
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.trigger =
function() { this.Bar.trigger.apply(this.Bar, arguments); };
this.bind = function() { this.Bar.bind.apply(this.Bar, arguments); };
this.Bar.find('clearButton').click(function() {
this.trigger('clear');
}
};
Toolbar.init();
Toolbar.bind('clear', function() { ... });
如果需要,您可以轻松创建一个处理包装的功能;这些中的任何一个,如你所愿:
function wrapperitize(wrapper, wrappee, method /*, more_methods...*/)
{
wrapper[method] = function() { wrappee[method].apply(wrappee, arguments); };
for(var i = 3; i < arguments.length; ++i)
wrapperitize(wrapper, wrappee, arguments[i]);
}
function wrapperitize(wrapper, wrappeeProp, method /*, more_methods...*/)
{
wrapper[method] = function()
{
wrapper[wrappeeProp][method].apply(wrapper[wrappeeProp], arguments);
};
for(var i = 3; i < arguments.length; ++i)
wrapperitize(wrapper, wrappeeProp, arguments[i]);
}
前者称为wrapperitize(this, this.Bar, 'trigger', 'bind')
,后者称为wrapperitize(this, 'Bar', 'trigger', 'bind')
(不同之处在于前者会使this
成为当前this.Bar
的包装器而后者会使this
成为未来this.Bar
可能成为的包装器。
(顺便说一句,顺便说一下,递归的一点点。这是为了避免有问题的变量捕获,因为JavaScript中的闭包工作方式。)
答案 2 :(得分:0)
如果您希望能够在Toolbar
对象上调用方法,则需要在那里定义它。如果您不需要以这种方式添加很多这些方法,您可以在工具栏对象本身中定义它们中的每一个:
var Toolbar = {
clear: function() { this.Bar.trigger('clear'); }
init: function(toolbar) {
this.Bar = $(toolbar); // scope is Toolbar object literal
this.Bar.find('clearButton').click(function() {
this.clear();
}
}
然而,如果你需要打电话给很多人,这很快就会变得难看。如果确实希望能够调用工具栏对象上jquery对象的所有可用方法,则可以尝试使用for in
循环遍历所有这些方法并添加它们到工具栏对象,但这将是乏味的,令人讨厌,低效,并可能导致一些错误。每当你想要在该对象上调用一个方法时,我只会使用$(toolbar)
,因为它摆脱了所有这些缺点。 :d