2013-05-21 61 views
3

我開始做jQuery插件,所以我沒有太多的經驗做這件事,我今天想做的事情是爲我正在開發的插件創建自定義事件。jQuery插件創建自定義事件

我的事情一個很好的例子來告訴你確切是我想要做的是bootstrap tooltip plugin,有了這個插件,我可以做這樣的事情:

$('.my-tooltip').tooltip('show'); 

強制插件做一個動作,在這種情況下,執行show()插件功能

對於我的特定情況下,我在做一個插件來定製驗證使用jQuery驗證插件圍繞一個網站的形式和我wan't做一些事情,如:

$('form#whatever').validateForm('showInlineChecks'); 

強制插件運行某些特定字段的驗證。

讓我們來看看我的代碼:

/* 
* jQuery plugin to validate forms around segurosdigitales 
* requires jquery validate plugin 
* */ 


if(typeof Object.create !== 'function'){ 
    Object.create = function(obj) { 
     function F(){}; 
     F.prototype = obj; 
     return new F(); 
    } 
} 


(function($){ 
    var validator = { 

     // init the plugin 
     init: function(options, element){ 
      var self = this; 

      self.options = $.extend({}, $.fn.validateForm.options, options); 

      self.elem = element; 
      self.$elem = $(element); 

      self.validateTheForm(); 
     }, 


     // Set default options for jQuery validate plugin 
     setValidationOptions: function(){ 
      var self = this; 

      // Default options for all forms around the app 
      // These are the default options for jquery validate plugin 
      var jQueryValidatePluginOptions = { 
       onfocusout: function(e){ 
        // Validate all elements when 'blur' event happens, except if it has a 'datepicker-open' class, I'm adding this class because datepicker causes that the input element loses focus and validation error is triggered 
        if(!$(e).hasClass('datepicker-open')){ 
         this.element(e); 
        } 
       }, 
       errorElement: 'span', 
       errorClass: 'error help-block', 
       errorPlacement: function(error, element){ 
        if(element.is('input[type="checkbox"]')){ 
         error.insertAfter(element.parent()); 
        } else { 
         error.insertAfter(element); 
        } 
       }, 

       // Highlight occurs when element has erros 
       highlight: function(element, errorClass, validClass){ 
        $(element).addClass(errorClass).removeClass(validClass); 

        var control_group = $(element).closest('.control-group, .controls-row'); 
        control_group.addClass(errorClass).removeClass(validClass); 

        // Remove any valid icon 
        control_group.find('i.icon-ok').remove(); 
       }, 

       // Unhighlight occurs when element is valid 
       unhighlight: function(element, errorClass, validClass){ 

        $(element).removeClass(errorClass).addClass(validClass); 

        // get the parent of the field 
        var control_group = $(element).closest('.control-group, .controls-row'); 

        // is field empty? 
        var element_is_empty = ($(element).val() === ''); 


        if (!element_is_empty && !control_group.find('i.icon-ok').length) { 
         var label = control_group.find('label'); 

         // Prevent to add more than one icon if control group contains more than one label (ie. when we have checkboxes and radio buttons) 
         $.each(label, function() { 
          $(this).prepend('<i class="icon-ok green"></i>'); 
          return false; 
         }); 

         // add class only if element is valid and not empty 
         control_group.removeClass(errorClass).addClass(validClass); 
        } 
       } 
      }; 

      // add other options depending of validateForm plugin options 
      if(self.options.errorMessages){ 
       jQueryValidatePluginOptions.messages = self.options.errorMessages; 
      } 

      if(self.options.rules){ 
       jQueryValidatePluginOptions.rules = self.options.rules; 
      } 

      if(self.options.showNotification){ 
       jQueryValidatePluginOptions.invalidHandler = function(event, validator){ 
        var errors = validator.numberOfInvalids(); 
        if(errors){ 
         generateNotification('error', false, 'Por favor corrige los errores en los campos resaltados en rojo para poder continuar.'); 
        } 
       } 
      } 

      return jQueryValidatePluginOptions; 

     }, 


     // Validate form 
     validateTheForm: function(){ 
      var self = this; 

      var validateOpts = self.setValidationOptions(); 

      self.$elem.validate(validateOpts); 
     } 

    }; 

    $.fn.validateForm = function(options){ 
     return this.each(function(){ 
      var validate = Object.create(validator); 
      validate.init(options, this); 
     }); 
    }; 

    $.fn.validateForm.options = { 
     errorMessages: null, 
     rules: null, 
     showNotification: true 
    } 

})(jQuery); 

我該怎麼辦呢?

+0

好插件的不同「標準」的方式,首先,你不想來初始化一個新的驗證每次你調用'validateForm'。 –

+0

謝謝@KevinB,那我該怎麼辦? –

+0

在元素上存儲對已創建實例的引用,如果元素已經有了所創建的實例,則調用由傳遞給插件的第一個參數指定的方法(如果它是字符串)。 (即將推出的樣本) –

回答

8

使用jquery創建,發佈和訂閱自定義事件非常簡單。

爲了發出定製事件,你只需撥打觸發

$(elem).trigger('myCustomEvent.myNS') 

我總是建議期運用命名空間,以方便管理自定義事件

然後,即可訂閱您事件像你一樣定期活動

$(elem).on('myCustomEvent.myNS', function(event) { 

}) 

您可以還可以添加傳遞給事件處理程序的附加參數,這樣

$(elem).trigger('myCustomEvent.myNS', ['p1', 'p2']) 

$(elem).on('myCustomEvent.myNS', function(event, param1, param2) { 
    console.log(param1) // outputs p1 
    console.log(param2) // outputs p2 
}) 

所以,總體來說,對一些用戶動作,比如說點擊一個按鈕,你會發出您的自定義事件,這樣

$(elem).on('click', 'button.save', function (e) { 
    $(elem).trigger('validate.myCtrl', [e, this]) 
}) 

另請注意,如果您的事件與您正在定義事件的對象上的某個方法具有相同的名稱,那麼當調用trigger時,jquery將嘗試調用此方法。爲了避免這種行爲,請使用jQuery的triggerHandler方法。

UPDATE:@cristiangrojas,我會建議你檢查設置的jQuery這裏https://github.com/shichuan/javascript-patterns/tree/master/jquery-plugin-patterns'