4

我有一个 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!

我希望能够触发clearToolbar 对象文字上的事件,而不是文字中引用的工具栏 DOM 对象。这可能吗,如果可以,我该怎么做?

4

3 回答 3

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
  1. 您需要this在 click 函数中维护引用。我用过$.proxy;有些人使用var self = this;

  2. Toolbar不是一个 jQuery 对象,所以它应该被包裹$()以访问 jQuery 的函数。还要在 click 函数中包装this引用Toolbar实例的 that。

于 2011-12-03T03:34:32.207 回答
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]);
}

前者将被称为 aswrapperitize(this, this.Bar, 'trigger', 'bind')而后者被称为wrapperitize(this, 'Bar', 'trigger', 'bind')(不同之处在于前者将成为当前this的包装器this.Bar,而后者将成为未来可能成为的this任何东西的包装器。this.Bar

(顺便说一句,注意一点点递归。这是为了避免有问题的变量捕获,因为闭包在 JavaScript 中的工作方式。)

于 2011-12-03T02:57:07.207 回答
0

如果您希望能够调用Toolbar对象上的方法,则需要在那里定义它。如果您不需要以这种方式添加很多这些方法,您可以在 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(); 
    }
}

但是,如果您需要调用其中很多,这将很快变得丑陋。如果您真的希望能够在 Toolbar 对象上调用 jquery 对象的所有可用方法,您可以尝试使用循环遍历所有方法并将它们for in添加到 Toolbar 对象,但这会很乏味、烦人阅读,效率低下,并可能导致一些错误。$(toolbar)每当您想对该对象调用方法时,我都会使用它,因为它消除了所有这些缺点。:D

于 2011-12-03T03:00:56.757 回答