【问题标题】:jQuery plugin create custom eventjQuery插件创建自定义事件
【发布时间】:2013-05-21 14:31:00
【问题描述】:

我开始做 jQuery 插件所以我没有太多经验,我今天想做的事情是为我正在开发的插件创建一个自定义事件。

bootstrap tooltip plugin 是一个很好的例子来告诉你我想要做什么,使用这个插件我可以做这样的事情:

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

强制插件做一个动作,本例执行show()插件函数

对于我的具体情况,我正在使用 jQuery 验证插件在网站周围自定义验证表单,我不想这样做:

$('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);

我该怎么做?

【问题讨论】:

  • 好吧,首先,你不想每次调用validateForm时都初始化一个新的验证器。
  • 谢谢@KevinB,那我该怎么办?
  • 在元素上存储对已创建实例的引用,如果元素已经表示已创建实例,则调用传递给插件的第一个参数指定的方法,如果它是一个字符串。 (样品即将推出)
  • 这是我所指内容的一个非常简化的版本:jsfiddle.net/NSEs8/1 请注意,我不是总是调用 init,而是仅在插件第一次运行时才调用 init。这里有更深入的版本:keith-wood.name/pluginFramework.html
  • 我已经看到您在插件中所做的更改,感谢您向我解释和做小提琴。

标签: jquery jquery-plugins


【解决方案1】:

使用 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])
})

另外请注意,如果您的事件与您定义事件的对象上的某些方法同名,jquery 将在调用trigger 时尝试调用此方法。为避免这种行为,请使用 triggerHandler jquery 方法。

更新:@cristiangrojas,我建议您在此处检查设置 jquery 插件的不同“标准”方法https://github.com/shichuan/javascript-patterns/tree/master/jquery-plugin-patterns'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-14
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多