覆盖元素级别的核心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 */ });
我不知道这是否有效。 试试吧。 它只来自我的大脑。