jQuery对象方法被多次调用

时间:2020-08-10 15:05:01

标签: javascript jquery jquery-plugins

我正在尝试编写一个jQuery方法,以监视给定表单元素内输入的更改:

(function($) {
    $.fn.filter = function(options) {
        console.log('Outside');

        var self = this;
        var settings = $.extend({}, options);        

        this.on('change', ':input', function(e) {
            console.log('Inside');

           $(self).serialize(); // Here is the problem

        });

        return this;
    }
})(jQuery);

$('#filter-form').filter();

当我使用$(self).serialize();时,该函数再次被调用。我希望“外部”部分仅在初始化时运行一次,而不是每次表单输入更改时都运行。

我不明白这里发生了什么。如果有人可以向我解释为什么会发生这种情况,我将不胜感激!

1 个答案:

答案 0 :(得分:1)

问题是您正在重新定义jQuery的filter方法,该方法在内部serialize方法中使用。如果您更改名称,它将起作用。 serialize的定义如下所示:

jQuery.fn.extend( {
    serialize: function() {
        return jQuery.param( this.serializeArray() );
    },
    serializeArray: function() {
        return this.map( function() {

            // Can add propHook for "elements" to filter or add form elements
            var elements = jQuery.prop( this, "elements" );
            return elements ? jQuery.makeArray( elements ) : this;
        } )
        .filter( function() {
            var type = this.type;

            // Use .is( ":disabled" ) so that fieldset[disabled] works
            return this.name && !jQuery( this ).is( ":disabled" ) &&
                rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
                ( this.checked || !rcheckableType.test( type ) );
        } )
        .map( function( _i, elem ) {
            var val = jQuery( this ).val();

            if ( val == null ) {
                return null;
            }

            if ( Array.isArray( val ) ) {
                return jQuery.map( val, function( val ) {
                    return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
                } );
            }

            return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
        } ).get();
    }
} );

工作示例:

(function($) {
  $.fn._filter = function(options) {
    console.log('Outside');

    var self = this;
    var settings = $.extend({}, options);

    this.on('change', ':input', function(e) {
      console.log('Inside');

      $(self).serialize();

    });

    return this;
  }
})(jQuery);

$('#filter-form')._filter();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="filter-form">
  <input type="text">
</form>