Override jQuery .val() function?

前端 未结 6 458
盖世英雄少女心
盖世英雄少女心 2020-12-01 10:41

Is there a way to easily override jQuery\'s val() function?

The reason I want to override it is that I want to add some processing each time a value is

相关标签:
6条回答
  • 2020-12-01 11:05

    I know the problem is old but just to give a full solution. In order for both the jQuery.val() and the jQuery.val(value) to work after override you need to override it properly and separately. Because when calling jQuery.val() then originalVal.call(this, value); will not work correctly.

    To do it in a correct way you need to do something like that when getting the value: originalVal.call(this);

    Here is a site where everything is explained: http://extremedev.blogspot.com/2012/01/override-jqueryval-and-jqueryvalvalue.html

    Regards, Roman

    0 讨论(0)
  • 2020-12-01 11:07

    You can store a reference to the original val function, then override it and do your processing, and later invoke it with call, to use the right context:

    (function ($) {
      var originalVal = $.fn.val;
      $.fn.val = function(value) {
        if (typeof value != 'undefined') {
          // setter invoked, do processing
        }
        return originalVal.call(this, value);
      };
    })(jQuery);
    

    Note that you can distinguish between a getter call $(selector).val(); and a setter call $(selector).val('new value'); just by checking if the value argument is undefined or not.

    0 讨论(0)
  • 2020-12-01 11:12

    If I am understanding you right, something like this should do the trick just fine:

    jQuery.fn.val = function (new_val) {
        alert("You set a val! How wonderful!");
        this.value = new_val;
    };
    

    Just make sure you include the regular functionality: getting values of selects and so on. Just stick that code after after the regular jQuery library.

    0 讨论(0)
  • 2020-12-01 11:17

    With this code you can override the "get" and "set" of .val() for specific elements:

    (function () {
    
        var __val = $.fn.val;
        $.fn.val = function (value) {
            if (this[0] && (this[0].$val_get || this[0].$val_set)) {
                if (arguments.length === 0) return this[0].$val_get();
                else return this[0].$val_set(value) || this;
            }
            return __val.apply(this, arguments);
        };
    
    })();
    

    Now you have to create two function properties on the DOM element - $val_get and $val_set:

    <input type="text" id="myInput" />
    <input type="text" id="someOtherInput" />
    
    <script>
    
        $('#myInput')[0].$val_get = function () {
            console.log('Got value from myInput!');
            return this.value;
        };
    
        $('#myInput')[0].$val_set = function (value) {
            console.log('Set value of myInput!');
             this.value = value;
        }
    
        //----
    
        $('#myInput').val('Hello!'); //Console: "Got value from myInput!"
        $('#myInput').val(); //Hello! | Console: "Set value to myInput!"
    
        $('#someOtherInput').val('Hello!'); //Console: ""
        $('#someOtherInput').val(); //Hello! | Console: ""
    
    </script>
    

    This is useful for creating components that orchestrate multiple controls.

    JsFiddle: https://jsfiddle.net/oj4gt2ye/6/

    0 讨论(0)
  • 2020-12-01 11:25

    I have something to add to CMS answer, my implementation would differ and be like this:

    (function ($) { var fnVal = $.fn.val;
        $.fn.val = function(value) {
            if (typeof value == 'undefined') {
                return fnVal.call(this);
            }
            var result = fnVal.call(this, value);
            $.fn.change.call(this);
            // here you can add some more implementation
            return result;
        };
    })(jQuery);
    

    observe the $.fn.change.call(this); will be called before exiting the val('') function this will trigger also the .change() on each val('') assignment.

    0 讨论(0)
  • 2020-12-01 11:26

    I know it's an old subject but it's first in google search and the answer is not completely right...

    For example if you try in the console $('#myinput').val() you should get the value of #myinput.

    But if you do $('#myinput').val(undefined) you should set the value of #myinput!( With the current answer and the comments of it, you will not set the value of #myinput)

    Here is an upgraded answer that use arguments.

    (function ($) {
      var originalVal = $.fn.val;
      $.fn.val = function(value) {
        if (arguments.length >= 1) {
          // setter invoked, do processing
          return originalVal.call(this, value); 
        }
        //getter invoked do processing
        return originalVal.call(this);
      };
    })(jQuery);
    

    if you want to pass all the arguments you can also use apply

    (function ($) {
      var originalVal = $.fn.val;
      $.fn.val = function(value) {
        if (arguments.length >= 1) {
          // setter invoked, do processing
        } else {
          //getter invoked do processing
        }
        return originalVal.apply(this, arguments);
      };
    })(jQuery);
    

    I hope it help!

    0 讨论(0)
提交回复
热议问题