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

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

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

我做了这个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数据命名空间或担心有人覆盖该密钥

基于sdleihssirhc的回答,但修改为仅适用于先前匹配的元素,因为您说“仅在一个

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

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

每个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实例。

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

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

我们走吧:

在开始之前,我们应该将默认的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 */ }); 

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