2012-10-12 25 views
1

我正在使用jQuery的事件系统来允许外部代码驱动我的插件。在我的事件中,处理程序的'this'被设置为事件绑定的元素,所以我自己访问插件方法的最佳方式是什么?管理jQuery插件上的事件处理程序的作用域

;(function($, window, document, undefined){ 
    var pluginName = "book"; 

    // Standard constructor 
    function Plugin(element, options){ 
     this.element = element; 
     this.options = $.extend({}, defaults, options); 

     this.init(); 
    } 

    // Simple init 
    Plugin.prototype.init = function(){ 
     this.setBindings(); 
    } 

    // Tie local methods to event channels 
    // so that external code can drive the plugin. 
    Plugin.prototype.setBindings = function(){ 
     var events = { 
      'book-open'  : this.open, 
      'book-next-page' : this.toNext, 
      'book-prev-page' : this.toPrev, 
      'book-cover'  : this.toFront, 
      'book-back'  : this.toBack 
     } 

     for(event in events){ 
      var fn = events[event]; 
      console.log(event); 
      this.$element.on(event, fn); 
     } 
    }; 

    // Event Handlers 
    Plugin.prototype.open = function(){ 
     // when called externally 'this' refers 
     // to the element the plugin was intialized on. 
     // I want to be able to call the plugin's 'private' 
     // methods, like someMethod() below. 
    }; 

    /* .... other event handlers ... */ 

    // 'Private' plugin methods 
    Plugin.prototype.someMethod = function(){ 
     // do something 
    } 

    // Wrap and return technique from @ajpiano & @addyosmani 
    $.fn[pluginName] = function (options) { 
     return this.each(function() { 
      if (!$.data(this, "plugin_" + pluginName)) { 
       $.data(this, "plugin_" + pluginName, 
        new Plugin(this, options)); 
      } 
     }); 
    } 

})(jQuery, window, document); 

回答

2

可以,而不是传递函数本身,调用将返回要执行的功能,其中一个封闭围绕插件的功能。

var createBookOpenFunction = function() { 
    var self = this; //since you execute this function on the plugin, "this" will be the plugin 
    return function() { 
     self.open(); 
    } 
}; 

然后,而不是调用...

this.$element.on(event, fn); 

你,而不是调用

this.$element.on(event, this.createBookOpenFunction()); 

所以现在,当函数被调用$元素,实际执行完成在插件对象上,因为它在“self”上关闭。
,您可以通过返回的函数将参数(如果有的话)提供给调用“self.open()”。

而且,这个线程可能会有所帮助: Controlling the value of 'this' in a jQuery event

(我不直接使用jQuery,所以我不熟悉什么都可用的API中,但这里的一些职位似乎有备用解决您的问题)

+1

你链接到的线程有答案。使用$ .proxy允许你在任何函数上定义一个任意范围。所以代码应该读这个。$ element.on(event,$ .proxy(fn,this)); – Thomas

+0

你能解释为什么有必要将函数包装在一个匿名函数中?这适用于我,但我不明白为什么在JavaScript中需要 – asumaran

+2

,“this”表示调用该函数的对象。如果我将函数指针附加到不同的对象上,那么该函数内部的“this”在执行时会有所不同。所以通过包装我想调用的函数,我可以创建一个对象“self”的引用,并调用“self”引用上的方法。这样我就可以控制我所调用的函数中“this”的含义。 – Caleb