只需说一句,我想对我的插件进行一点分支编写,并决定能够"命名"它们。到目前为止,将$.method
重写为$.namespace.method
是很容易的。
我遇到的问题是制作元素方法,如$('element').method()
,但要使用名称空间;例如CCD_ 4。我已经尝试了一些变通方法,可以创建$.fn.namespace.method
,但是,当我从该方法中调用this
时,我只得到$.fn.namespace
,而不是我想要得到的'element'
。
示例:如果我调用$('body').namespace.test()
,那么在方法test
中,我希望this
是元素<body></body>
任何想办法实现这一目标的帮助都将不胜感激。可能只是像往常一样过度思考。
目前正在尝试类似$('body').namespace().method()
的可能解决方案,到目前为止,效果不太好…:P
如果不需要与IE8兼容,可以使用Object.defineProperty.
工作示例:
Object.defineProperty($.fn, 'namespace', {
get: function(){
var t = this;
return {
lowercasehtml: function(){
return t.html(function(_,h){ return h.toLowerCase() });
}
}
}
});
$('#a').namespace.lowercasehtml(); // changes the html of #a to lowercase (yes, it's stupid, I know)
演示
但我不相信这样命名名称空间是个好主意。我会简单地定义
$.fn.namespace_lowercasehtml = function() ...
这就是我个人为jQuery的应用程序特定扩展所做的。
虽然我不建议这样做,但您可以为每次调用namespace()
:生成一个新对象
(function($){
var plugin = {
test: function (){
console.log(this);
}
};
var methods = Object.keys( plugin );
$.fn.namespace = function (){
var self = this,
localMethods = {};
$.each(methods, function () {
localMethods[ this ] = plugin[ this ].bind(self);
});
return localMethods;
};
}(jQuery));
小提琴在这儿:http://jsfiddle.net/WaXzL/
您可以为较旧的浏览器polyfill Object.keys
,也可以手动创建methods
数组。
bind
也是如此:要么用polyfill填充,要么用call
手动填充。
以下是一个可以在旧浏览器中工作的版本:
(function($){
var plugin = {
test: function (){
console.log(this);
}
};
var methods = [];
for ( var i in plugin ) {
if ( plugin.hasOwnProperty(i) ) {
methods.push(i);
}
}
$.fn.namespace = function (){
var self = this,
localMethods = {};
$.each(methods, function (i, method) {
localMethods[ method ] = function () {
plugin[ method ].call( self );
};
});
return localMethods;
};
}(jQuery));
这是小提琴:http://jsfiddle.net/WaXzL/1/
不如做:
$('element').namespace.method()
你可以简化它并进行
$('element').namespace('method')
相反?这要简单得多:
(function($){
var methods = {
test: function(a, b){
console.log(this, a, b);
}
};
$.fn.namespace = function(method){
var params = Array.prototype.slice.call(arguments, 1);
return methods[method].apply(this, params);
};
}(jQuery));
然后您可以执行类似的操作:$('body').namespace('test', 1, 2);
更好的解决方案是只有一个主方法,并将方法名称作为字符串传递:
(function($){
var plugin = {
test: function (){
console.log(this);
},
otherTest: function (){
console.log(this);
}
};
$.fn.namespace = function (method){
var args = Array.prototype.slice.call(arguments, 1);
return plugin[ method ].call(this, args);
};
}(jQuery));
小提琴在这儿:http://jsfiddle.net/yYNDH/