2013-05-21 59 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'