覆盖元素级别的核心jQuery函数

时间:2011-04-22 22:16:22

标签: jquery function override element core

是否可以在元素级别覆盖核心jQuery函数,因此举个例子,我想仅在一个< select> 元素上覆盖 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函数的对象的行为,这对我来说有点太多了。

任何帮助将不胜感激。 谢谢。

5 个答案:

答案 0 :(得分:4)

基于sdleihssirhc的回答,但修改为仅适用于之前匹配的元素,因为您说“仅在一个< select>元素”。

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

答案 1 :(得分: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数据命名空间或担心有人覆盖该密钥

答案 2 :(得分:2)

这个小片段允许覆盖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);            
    };
};

答案 3 :(得分:1)

每个jQuery对象都包含一个selector属性,其中包含(duh)用于获取元素的原始选择器(我根本没用过它,所以我不确定会发生什么当你通过一系列方法时,它就会出现。)

因此,您可以将val方法包装在检查selector属性的函数中,然后决定是使用您的函数还是原始函数。它看起来像这样:

$.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实例。

(另外,这本身就非常简单;你需要相应地修改/增强它。)

答案 4 :(得分:1)

是的,这是一个很好的问题。我永远不会尝试这件事。

我们走吧:

在开始之前,我们应该将默认的val函数复制到另一个地方:

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

我会写一个函数global来捕获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 */
});

我不知道这是否有效。试试吧。它只来自我的大脑。