是否可以在元素级别覆盖核心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函数的对象的行为,这对我来说有点太多了。
任何帮助将不胜感激。 谢谢。
答案 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 */
});
我不知道这是否有效。试试吧。它只来自我的大脑。