问题 覆盖元素级别的核心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函数的所有对象的行为,这对我来说有点太多了。
任何帮助将不胜感激。
谢谢。
4659
2018-04-22 22:16
起源
答案:
我做了这个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
2017-11-13 01:26
答案:
我做了这个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
2017-11-13 01:26
根据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);
}
};
4
2018-04-22 22:30
这个小片段允许覆盖jQuery方法。
我发现@BT的答案相当糟糕,因为它在每次使用函数时都会创建额外的回调。因此,如果你将它应用于1000个元素,每个函数1000个 val()
叫做!
我的 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
2018-02-09 15:06
每个jQuery对象都包含一个 selector
property,包含(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实例。
(另外,这本身就非常简单;你需要相应地修改/增强它。)
1
2018-04-22 22:23
是的,这是一个很好的问题。我永远不会尝试这件事。
我们走吧:
在开始之前,我们应该将默认的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 */
});
我不知道这是否有效。尝试一下。它只来自我的大脑。
1
2018-04-22 22:30