2012-10-12 47 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