如何使 jQuery 插件函数可调用以供独立使用,而不对集合进行操作
Posted
技术标签:
【中文标题】如何使 jQuery 插件函数可调用以供独立使用,而不对集合进行操作【英文标题】:How to make a jQuery plugin function callable for stand-alone use, that does not operate on a collection 【发布时间】:2012-09-07 07:57:44 【问题描述】:我阅读了jquery documentation of plugin authoring 并且对此很熟悉。但是,给出的示例总是对一组先前匹配的元素进行操作。我想创建一个可以同时做这两个功能的函数:
// example usage of my to-be-created plugin function
// this is the way described in the docs, and I know how to do that
$("a").myFunction ()
// but I also want to be able to call the function without a collection:
$.myFunction ();
如果$.myFunction ()
在没有要操作的集合的情况下被调用,它将创建自己的要匹配哪些元素的集合——一种初始化过程(但不一定只运行一次)。此外,$.myFunction ()
应该保持可链接性。
我想要实现的伪代码:
// [...]
function myFunction ():
if (notCalledOnACollection)
// this should run when called via $.myFunction ()
$elements = $("a.myClass");
else
$elements = $(this);
return $elements.each (function ()
// do sth. here
);
我真的很想将所有函数实现/功能保留在一个函数定义中,而不是在 jQuery 对象内的两个不同位置有两个单独命名的函数或两个同名函数。
当然我可以添加一个参数myFunction (do_init)
来指示要执行if
语句的哪个分支,但这会使我的参数列表变得混乱(我想将这种方法用于多个插件,并且会有参数到myFunction ()
,为了简单起见,我在这里省略了)。
有什么好的建议吗?
【问题讨论】:
【参考方案1】:只需在插件定义中添加另一个引用,您就可以轻松使用标准插件代码:
(function( $ )
$.myPlugin = $.fn.myPlugin = function(myPluginArguments)
if(this.jquery)
//"this" is a jquery collection, do jquery stuff with it
else
//"this" is not a jquery collection
;
$.fn.myPlugin.otherFunc = function()
;
)( jQuery );
这里唯一的区别是$.myPlugin =
部分,它允许你直接调用你的插件而不运行jquery 的选择器函数。如果您决定需要其他函数或属性,可以将它们创建为插件的属性。
用法:
//using a selector (arguments optional)
$(".someClass").myPlugin();
//using the options variable - or whatever your arguments are
$.myPlugin(id: "someId");
//accessing your other functions/properties
$.myPlugin.otherFunc();
【讨论】:
我的解决方案存在严重问题。我已经在 jsfiddle 上复制了你的方法:jsfiddle.net/pnpbU 但是一旦我运行$.myPlugin ()
,所有测试的浏览器都会消耗 100% 的 CPU 并卡住(在 Linux 和 Windows 上使用 FF 进行测试,在 Mac 上使用 Safari 进行测试)。
我的机器上没有看到这个问题。而我现在正在恐龙身上。此外,jsfiddle 不应该用于性能测试,他们已经加载了一堆额外的东西。我也在本地进行了测试,也没有看到那里的问题。我真的怀疑你看到的和这段代码有什么关系。
你取消注释jsfiddle的js部分的行了吗?否则它不会运行!我现在在大学,可以使用一堆计算机,我可以在 3 台物理上不同的机器上重现 100% 的 CPU 消耗。使用jsfiddle.net/pnpbU(取消注释最后一行)并点击运行将阻止/结束 Fedora 17 上的脚本:Firefox 14.0.1、Chrome 22;视窗 7:火狐 14、IE9; OS X Lion:Safari 5、Firefox 14。所以它是明确可重现的。这个和jsfiddle没有关系,把那个脚本和jQuery 1.8.0一起复制运行,效果是一样的。
啊,现在我知道你哪里出错了。问题不在于我上面的代码,而是你添加到它的$(this).each
。当你不发送选择器时,你不能以同样的方式使用this
(没有选择器,没有集合,因此没有集合对象)。我已经更新了您的 fiddle,以展示带有和不带有选择器的 this
对象的区别。
啊,你是对的,我混淆了 if/else 分支。我现在做if (this.jQuery === undefined) // build the collection /* do sth. with the collection */
以上是关于如何使 jQuery 插件函数可调用以供独立使用,而不对集合进行操作的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jQuery UI 使 datatables.js 的列可调整大小