如何包装jQuery函数 [英] How to wrap the jQuery function
问题描述
问题
我想知道在保留所有功能的同时包装jQuery函数的最佳方法.本质上,我想调用$('#someId')
,但通过包装函数,修改参数并将其传递给原始jQuery函数,使它像$('#' + id + 'someId')
一样运行.
I'd like to know the best way I can wrap the jQuery function while retaining all functionality. Essentially I want to call $('#someId')
but have it operate as $('#' + id + 'someId')
by wrapping the function, modifying the arguments, and passing it through to the original jQuery function.
动机
我有一段JS,它将重用连接并传递给jQuery的相同变量winId
.不用写
I have a section of JS that will reuse the same variable winId
which is concatenated and passed to jQuery. Instead of writing
$('#' + winId + 'someId').html();
$('#' + winId + 'someOtherId').css();
...
$('#' + winId + 'someThirdId').text();
在整个文件中,我想包装jQuery函数,以便我可以调用
throughout the whole file, I want to wrap the jQuery function so I can just call
$('#someId').html();
$('#someOtherId').css();
...
$('#someThirdId').text();
并在通向$
之前添加winId
.
我的尝试
这就是我想包装的东西:
Here's what I'm thinking as a wrapper:
(function() {
var fn = $;
return $ = function() {
for ( var i = 0; i < arguments.length; i++ ) {
if ( typeof arguments[i] == 'string') {
arguments[i] = /* code to add in winId, omitted */
}
}
return fn.apply( this, arguments );
}
})();
这很好用,除了显然没有像$.ajax
这样的方法可用:
This works great, except that obviously none of the methods like $.ajax
are available:
Uncaught TypeError: Object function () {
for ( var i = 0; i < arguments.length; i++ ) {
if ( typeof arguments[i] == 'string' ) {
arguments[i] = /* code to add in winId, omitted */
}
}
return fn.apply( this, arguments );
} has no method 'ajax'
注意:我知道我可以使用jQuery.extend($, jQuery)
复制对象,但是我对一种比它更优雅的解决方案感兴趣,如果可能的话.
Note: I know I could copy the object over using jQuery.extend($, jQuery)
, but I'm interested in a more elegant solution than that if possible.
推荐答案
这是另一种实现:
(jQuery.fn.init = (function (init) {
return function (selector) {
if (typeof selector === 'string' && selector[0] === '#') {
arguments[0] = selector.replace('#', '#prefix_');
}
return init.apply(this, arguments);
};
})(jQuery.fn.init)).prototype = jQuery.fn;
$(function () {
console.log($('#test').length);
console.log($.ajax);
});
后续问题:如何仅在封闭中应用此内容?例如,在一个对象内.
也许具有允许添加命名装饰器并将其删除的功能,例如:
Perhaps with functions that allows to add named decorators and remove them, something like:
HTML
<div id="prefix_test"></div>
JS
var decJQ = (function (decJQ, $) {
var decorators = {},
init = $.fn.init;
($.fn.init = function () {
for (var k in decorators) {
if (decorators.hasOwnProperty(k)) {
arguments = decorators[k].apply(this, arguments);
}
}
return init.apply(this, arguments);
}).prototype = $.fn;
return $.extend(decJQ, {
decorate: function (name, fn) {
decorators[name] = fn;
},
undecorate: function (name) {
delete decorators[name];
}
});
})(window.decJQ || {}, jQuery);
decJQ.decorate('idPrefix', function (selector) {
if (typeof selector === 'string' && selector[0] === '#') {
arguments[0] = selector.replace('#', '#prefix_');
}
return arguments;
});
$(function () {
console.log($('#test').length); //1
decJQ.undecorate('idPrefix');
console.log($('#test').length); //0
});
您还可以尝试一些非常简单的方法,例如:
EDIT 2: You could also go for something extremely simple, such as:
(function ($) {
//use $ which has been wrapped
})(function () {
//do some manipulations
return jQuery.apply(this, arguments);
});
这篇关于如何包装jQuery函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!