Javascript 用函数包装jQuery插件
假设我有以下简单的插件:Javascript 用函数包装jQuery插件,javascript,jquery,function,namespaces,extend,Javascript,Jquery,Function,Namespaces,Extend,假设我有以下简单的插件: (function ( $ ) { $.fn.greenify = function() { this.css( "color", "green" ); return this; }; }( jQuery )); 我不想对插件本身做任何更改,但我想用另一个函数包装并扩展其名称空间,如下所示: (function($) { $.fn.myFunction = function () { (functio
(function ( $ ) {
$.fn.greenify = function() {
this.css( "color", "green" );
return this;
};
}( jQuery ));
我不想对插件本身做任何更改,但我想用另一个函数包装并扩展其名称空间,如下所示:
(function($) {
$.fn.myFunction = function () {
(function ($) {
$.fn.greenify = function () {
this.css("color", "green");
return this;
};
}(jQuery));
};
})(jQuery);
所以我可以这样调用插件函数:
$(selector). myFunction().greenify();
基本上我想禁用直接调用“greenify”函数
有可能吗?如果要创建自己的上下文,一种方法是返回一个包含一组函数的对象:
(function($) {
$.fn.myFunction = function () {
// Cache jQuery object
var $this = this;
// Return interface that acts on jQuery object
return {
greenify: function () {
$this.css("color", "green");
return $this;
}
};
};
})(jQuery);
然后,您可以使用以下方法调用它:
$(selector).myFunction().greenify();
编辑:但是作为一个警告,当您这样做时,您将在调用
.myFunction
后离开jQuery链接上下文,这在代码中可能会非常混乱。我认为您谈论的是方法链接,这是jQuery方法的优点。按如下方式定义新方法,但保持greenify()
不变:
(function($) {
$.fn.myFunction = function () {
return this.each(function() {
//Do stuff
});
};
})(jQuery);
(函数($){
$.fn.greenify=函数(){
css(“颜色”、“绿色”);
归还这个;
};
}(jQuery));
(函数($){
$.fn.myFunction=函数(){
返回此值。每个(函数(){
$(this.css({边框:'1px纯黑',文本对齐:'center'});
});
};
})(jQuery);
$('.box').myFunction().greenify()代码>
颜色更改
只要您的myFunction
返回this
,您应该能够链接任何您想要的内容
(function ( $ ) {
$.fn.greenify = function() {
this.css( "color", "green" );
return this;
};
}( jQuery ));
(function($) {
$.fn.myFunction = function () {
// Do some stuff
return this;
};
})(jQuery);
$(selector).myFunction().greenify();
编辑:如果重点是“禁止直接调用greenify”,那么首先为什么要扩展jQuerygreenify可以嵌套并通过传递某种参数触发。比如:
(function($) {
$.fn.myFunction = function (options) {
// Do some stuff
if (options.greenify) {
this.css("color", "green");
}
return this;
};
})(jQuery);
$(selector).myFunction({greenify: true});
。。。或者您可以将greenify定义为一个函数(而不是插件)并调用它。但是定义插件的意义在于,它们可以被全局调用。您肯定不想采用当前显示的方法,因为每次调用myFunction时,它也会分配greenify。只需使用myFunction
插件,为构建的jQuery对象指定一个标志,然后在greenify中检查该标志
(函数($){
$.fn.myFunction=函数(){
this.greenMarker=true;
归还这个;
};
$.fn.greenify=函数(){
如果(!this.greenMarker)返回此;
css(“颜色”、“绿色”);
归还这个;
};
})(jQuery);
$('.f').greenify();
$('.g').myFunction().greenify()代码>
没有绿色
Green Me
问题还不清楚,但我假设简单的插件“greenify”是第三方或其他“被迫使用”的插件,无论出于何种原因,您都无法更改。我们还假设它实际上是一个相当复杂的插件,并且为了这个问题而简化了它
这意味着
- 你不能改变它
- 您不能在包装器中复制整个插件
覆盖内容的常用方法是复制一份,然后让新版本执行您想要的操作,可能会调用旧版本,例如:
var oldfoo = foo;
foo = function() {
alert("foo called");
oldfoo(); // or oldfoo.apply(this) to be clearer
}
这里也可以应用相同的原则,但将“foo”(在上面的示例中)设为null-以消除它,例如:
var oldfoo = foo;
newfoo = function() {
alert("foo called");
oldfoo(); // or oldfoo.apply(this) to be clearer
}
foo = null;
复杂的是jquery并希望保持方法链接,这可以通过存储“this”并根据需要应用它来实现
以下是完整的代码和解释注释:
// The original plugin to be wrapped
(function ( $ ) {
$.fn.greenify = function() {
// changed to background-color for more impact (demo purposes)
this.css( "background-color", "lightgreen" );
return this;
};
}( jQuery ));
(function($) {
// allow this to be referred to later
// inside another loop where 'this' is something else
var me = this;
// take a copy of the original
// this stays inside the scope of (function($)) so can't be seen outside
me.original_greeny = $.fn.greenify;
// provide a wrapper
$.fn.myFunction = function () {
// the jquery elements for applying later
var $this = $(this)
// exported function
return {
greenify: function() {
// Call the original function with the jquery elements
// and return them for chaining
return me.original_greeny.apply($this)
}
};
};
})(jQuery);
// Now remove the original completely
(function ( $ ) {
$.fn.greenify = null;
}(jQuery));
// As desired, also demonstrating chaining still works
$("#a").myFunction().greenify().css("font-style", "italic")
// Confirm that the original has been removed
// gives error $(...).greenify is not a function
try {
$("#a").greenify()
} catch(e) {
$("#a").text("error on $().greenify: " + e)
}
这也将允许直接调用greenify
。问题的关键是如何避免这种情况。这样做的目的是什么?@Vohuman同意了解原因会很有用-这可能是一个任务-或者他们想用一些前/后代码包装其他插件-或者他们不喜欢原始名称-或者他们只是想引起他们不知道如何做:你是对的,我应该解释更多,对不起。这只是一个实验,我正在努力学习如何安全地使用第三方插件@freedomn-m提出了一些原因,解释了为什么更改或扩展插件名称空间是有用的,我希望采用这种方法的主要原因之一是防止第三方插件中出现重复函数名的问题。通过对freedomn-m解决方案稍作修改,我成功地使其工作。所有其他答案在某些方面都是正确的,但您的解决方案正是我所寻找的。非常感谢你。