2011-11-30 50 views
2

我想寫一個插件,將對我選擇的dom元素內的某些輸入字段上的任何更改作出反應。jquery插件無法訪問插件定義中引用的對象

我的插件定義如下:

(function($){ 

    var methods = { 
     init : function(options) { 
      console.log(this.obj); 
      var inputs = $('input', this.obj); 
      $.each(inputs, function(i, domElement){ 
       $(this.obj).premiumUpdatable('addEvent', $(domElement)); 
      }) 

     }, 
     addEvent: function(element){ 
      $(element).bind('change',function(){ 
       console.log($(element).val()); 
      }) 
     } 
    }; 

    $.fn.premiumUpdatable = function(method) { 

     return this.each(function(){ 
      var obj = $(this); 
      if (methods[method]) { 
       return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1)); 
      } else if (typeof method === 'object' || ! method) { 
       return methods.init.apply(this, arguments); 
      } else { 
       $.error('Method ' + method + ' does not exist on jQuery.premiumUpdatable'); 
      }  
     }); 
    }; 
})(jQuery); 

然後,我打電話給我的插件,如:

$('div.updatable').premiumUpdatable(); 

問題是,當我嘗試的console.log(this.obj)中的一個方法定義我總是得到未定義。我希望得到我在插件定義中的參考,obj = $(this); ...我希望得到$(this)元素。

我需要應用於多個頁面上的DOM元素的這個插件,但如果我不能得到的參考DOM元素......我真的不能告訴哪個是哪個了....

任何幫助將不勝感激...

PS:我可能不會問正確的問題,因爲我仍然是新的jQuery插件開發,但這個問題似乎真的錯過了我,我無法克服它。

回答

0

執行此操作時調用init()方法:

return methods.init.apply(this, arguments); 

this是當前的DOM元素,你在init()方法this顯然期待成爲您的插件實例。

另一個問題是您的obj屬性在.each()回調中聲明,所以它在init()方法中無論如何都不可見。

這裏的鏈接提出了一個基礎結構開發的jQuery插件:
jQuery plugin boilerplate


互補的插件開發,這裏有關於JavaScript中的「這個」關鍵字的鏈接。要真正瞭解它,我認爲在uncomprehensible情況下不會落得這是非常重要的,同時發展:

The this keyword
What is ‘this’ in JavaScript?
BETTER JAVASCRIPT–WHAT IS THIS?

1

我包你的代碼的jQuery插件我能找到的最堅實的插件結構至今。這也將解決你的問題不能訪問你的插件範圍內的對象

<!DOCTYPE html> 
<html> 
<head> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script> 
    <script> 
     (function($){ 
      $.premiumUpdatable = function(el, options){ 
       // set a reference to the class instance 
       var base = this, 
        // store all inputs for reuse 
        inputs; 

       // store the options in base.o 
       base.o = $.extend({},$.premiumUpdatable.defaultOptions, options); 
       // set a reference to the jquery object 
       base.$el = $(el); 
       // set a reference to the DOMNode 
       base.el = el; 

       /** 
       * @public 
       * This function can be accessed from outside the plugin scope with 
       * $('.premium').data('premiumUpdatable').publicFunction(); 
       */ 
       this.publicFunction = function(){}; 

       var initInputs = function(){ 
        inputs = $('input', base.$el.attr('id')).each(function(i, domElement){ 
         $(domElement).bind('change', function(){ 
          console.log('input ' + $(this).attr('id') + ' changed to: ', $(this).val()); 
         }); 
        }); 
       }; 

       /** 
       * @private 
       * self-executing constructor 
       */ 
       (function init(){ 
        initInputs(); 
       })(); 
      }; 
      // defining the default options here makes it posible to change them globaly with 
      // $.premiumUpdatable.defaultOption.myValue = 'value' 
      // or 
      // $.premiumUpdatable.defaultOption = { myValue:'value' } 
      // before the first initialisation for the objects to come 
      $.premiumUpdatable.defaultOptions = {}; 
      $.fn.premiumUpdatable = function(options){ 
       return this.each(function(index, element){ 
        // prevents a second initialisation of the object if data('premiumUpdatable') is already set 
        if (undefined == $(element).data('premiumUpdatable')) { 
         // stores a referenze to the PluginClass, to that your able to access its public function from outside with 
         // $('.premium').data('premiumUpdatable').publicFunction(); 
         $(element).data('premiumUpdatable', new $.premiumUpdatable(element, options)); 
        } 
       }); 
      }; 
     })(jQuery); 

     $(document).ready(function(){ 
      $('.premium').premiumUpdatable(); 
     }); 
    </script> 
</head> 
<body> 
    <div class="premium"> 
     <form> 
      <input id="inputText" type="text" value="" /><br /> 
      <input id="inputPassword" type="password" value="" /><br /> 
      <input id="inputCheckbox" type="checkbox" value="something checked" /><br /> 
      <input id="inputRadio" type="radio" value="1" /> 
     </form> 
    </div> 
</body> 
</html>