web-dev-qa-db-ja.com

jQuery .val()関数をオーバーライドしますか?

JQueryのval()関数を簡単にオーバーライドする方法はありますか?

それをオーバーライドしたい理由は、要素に値が設定されるたびに処理を追加したいからです。また、myVal()などの別のカスタム値セッターを作成したくありません。

28
7wp

私はそれが古い主題であることを知っています、しかしそれはグーグル検索で最初であり、答えは完全に正しくありません...

たとえば、コンソール$('#myinput').val()で試行すると、#myinputの値を取得する必要があります。

ただし、$('#myinput').val(undefined)を実行する場合は、#myinputの値を設定する必要があります!(現在の回答とそのコメントでは、#myinputの値を設定しません)

これは、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);

すべての引数を渡したい場合は、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);

お役に立てば幸いです。

18

元のval関数への参照を保存し、それをオーバーライドして処理を実行し、後でcallを使用して呼び出して、適切なコンテキストを使用できます。

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

value引数がundefinedであるかどうかを確認するだけで、ゲッター呼び出し$(selector).val();とセッター呼び出し$(selector).val('new value');を区別できることに注意してください。

48
CMS

私は問題が古いことを知っていますが、完全な解決策を与えるためだけです。オーバーライド後にjQuery.val()とjQuery.val(value)の両方が機能するためには、適切かつ個別にオーバーライドする必要があります。 jQuery.val()を呼び出すときは、originalVal.call(this、value);正しく動作しません。

正しい方法でそれを行うには、値を取得するときに次のようなことを行う必要があります。originalVal.call(this);

ここにすべてが説明されているサイトがあります: http://extremedev.blogspot.com/2012/01/override-jqueryval-and-jqueryvalvalue.html

よろしく、ローマ

2
Roman

このコードを使用すると、特定の要素の.val()の「get」と「set」をオーバーライドできます。

(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);
    };

})();

次に、DOM要素に2つの関数プロパティを作成する必要があります-$val_getおよび$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>

これは、複数のコントロールを調整するコンポーネントを作成する場合に役立ちます。

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

1
Raphael

私があなたを正しく理解しているなら、このような何かがうまくいくはずです:

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

Selectの値の取得などの通常の機能が含まれていることを確認してください。そのコードを貼り付けるだけですafter通常のjQueryライブラリの後に。

1
Reid

CMSの回答に追加するものがあります。実装は異なり、次のようになります。

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

$ .fn.change.call(this);は、val( '')関数を終了する前に呼び出されます。これにより、各val( '')割り当てで.change()もトリガーされます。

0
ungalcrys