要素レベルでコアjQuery関数をオーバーライドする

core element function jquery override
要素レベルでコアjQuery関数をオーバーライドする

要素レベルでコアjQuery関数をオーバーライドすることは可能ですか?そのため、例として、1つの*要素でのみ val()*関数をオーバーライドしたいと思います。

このようなことをしたら

var element = $('select');
var old_val = element.val;
element.val = function () {
  console.log('The new val');
  return old_val.apply(this, arguments);
}
element.val(19);

期待どおりに動作しますが、新しいjQueryインスタンスで同じフィールドにアドレスするとすぐに

var element = $('select');
element.val(19);

jQueryオブジェクトの新しいインスタンスがあるため、動作しなくなります。 * $。fn.val *関数をいじると、val関数をサポートするすべてのオブジェクトの動作を変更します。

任意の助けをいただければ幸いです。 ありがとうございました。

  11  2


ベストアンサー

sdleihssirhcの回答に基づきますが、「* one *要素のみ」と言ったため、以前に一致した要素にのみ適用されるように変更しました。

element.data('custom_val', function() {
    console.log('The new val');
});

$.fn.old_val = $.fn.val;
$.fn.val = function () {
    var custom_val = this.data('custom_val');
    if (custom_val) {
         return custom_val.apply(this, arguments);
    } else {
         return this.old_val.apply(this, arguments);
    }
};

4


あなたが話していることだけを行うために、このjquery拡張を作成しました。

// overrides a method thats supposed to be called on a single node (a method like val)
$.fn.overrideNodeMethod = function(methodName, action) {
    var originalVal = $.fn[methodName];
    var thisNode = this;
    $.fn[methodName] = function() {
        if (this[0]==thisNode[0]) {
            return action.apply(this, arguments);
        } else {
            return originalVal.apply(this, arguments);
        }
    };
};

Daveの答えに対するボーナス-jqueryデータ名前空間を汚染したり、誰かがそのキーを上書きすることを心配する必要はありません。

4


この小さなスニペットにより、jQueryメソッドをオーバーライドできます。

関数を使用するたびに余分なコールバックが作成されるため、@ BTの回答は非常に悪いと感じています。 したがって、1000個の要素に適用する場合、すべての `val()`の1000個の関数が呼び出されます!

私の `overrideNodeMethod`は何度でも要素に適用できます。 基本的には `hasOverriddenMethod`データをチェックします

var originaljQueryMethods = {};
for(var method in $.fn){
    originaljQueryMethods[method] = $.fn[method];
};

$.fn.callOriginalMethod = function(method, args) {
    return originaljQueryMethods[method].apply(this, args);
};

$.fn.overrideNodeMethod = function(method, callback) {
    var dataKey = "hasOverriddenMethod." + method;
    $(this).callOriginalMethod("data", [dataKey, callback]);
    $.fn[method] = function() {
        var callback = $(this).callOriginalMethod("data", [dataKey])
        if (callback) {
            return callback.apply(this, arguments);
        }
        return $(this).callOriginalMethod(method, arguments);
    };
};

2


すべてのjQueryオブジェクトには、要素を取得するために使用された元のセレクターを含む(duh) `selector`プロパティが含まれています(実際にはまったく動作していません。メソッドのチェーンを通じて)。

したがって、 selector`プロパティをチェックし、関数を使用するかオリジナルを使用するかを決定する関数で、 val`メソッドをラップできます。 これは次のようになります。

$.fn.old_val = $.fn.val;
$.fn.val = function () {
    if (this.selector === 'select') {
        console.log('The new val');
    }
    return this.old_val.apply(this, arguments);
};

あなたは基本的にこれを以前に持っていました、私はそれをすべての新しいjQueryインスタンスに適用するようにそれを微調整しています。

(また、これはそれ自体はかなり単純化されています;それに応じてそれを修正/強化したいと思うでしょう。)

1


ええ、これは素晴らしい質問です。 私はこのことを決して試しません。

行こう:

開始する前に、デフォルトのval関数を別の場所にコピーする必要があります。

jQuery.fn.oldval = jQuery.fn.val;

val()関数をキャッチする関数をグローバルに記述します。

jQuery.fn.val = function(value) {
   var t = jQuery(this);
   if(t.get(0)) {
      //Check for overwritten function
      var func = jQuery.data(t.get(0), 'val-function');
      if(jQuery.isFunction(func)) {
         return func(value);
      }
   }
   //Use old function
   return jQuery(this).oldval(value);
};

その後、以下を使用してElement-Dataに関数を設定できます。

var element = jQuery(...);
jQuery.data(element.get(0), 'val-function', function(value){
   /* Your Function here */
});

これが機能するかどうかはわかりません。 それを試してみてください。 それは私の脳からのものです。

1


タイトルとURLをコピーしました