最好的插件开发实践,以避免污染jQuery命名空间?

时间:2009-12-01 16:20:51

标签: jquery jquery-plugins namespaces

我创建了一个jQuery插件,允许用户与树交互(创建,更新,删除节点)。至少有十几种与树交互的方法。理想情况下,我不想像现在这样使用所有这些特定于树的方法来污染jQuery命名空间,因为每个方法都为命名空间冲突提供了额外的机会。我只想要一种方法来激活插件本身,所以我希望重构。

$('ol#tree').tree(options) // just a single jQuery method for my plugin is fine…
$('li#item4').moveNode('li#item6') // …however, we also have this supporting method
$('ol#tree').appendNode(node) // …and this one
$('li#item2').expandBranch() // …and this one, etc.

将接口暴露给激活的DOM元素及其不污染jQuery名称空间的子元素有哪些做法?

我玩弄了保存创建树时返回的jQuery对象。

var tree =  $('ol#tree').tree();

此树对象本身将扩展为包含方法。不幸的是,由于树本身正在被定期操作,因此存在使该对象的状态与父DOM元素及其子元素的状态不同步的风险。我不确定在该对象中保持状态是否值得,因为DOM本身将始终具有当前状态。

我还考虑使用命名空间(通过John Resig的Space plugin):

$('ol#tree').tree()
$('ol#tree').tree.appendNode(node)
$('ol#tree').tree.item('li#item2').expandBranch()

你如何处理这个问题?你能指点我一些现有的插件来解决这个问题吗?我可以从中学到哪些代码?

2 个答案:

答案 0 :(得分:2)

使用简短明了的名字!不是枯燥的,但是例如 nicetree (嘿,这只是一个想法)!将界面放入名称中。像这样:

$("ol#tree").nicetree.appendNode(node);
$("ol#tree").nicetree.item("li#item2").expandBranch();

另一个想法是按照您的建议返回的对象,但不要更新此对象。该对象仅是对真实对象或DOM的引用。这会增加一个间接层,这可能是您可能接受的,也可能是不可接受的。

我作为一个插件用户想要两个解决方案,但稍微喜欢第一个。

答案 1 :(得分:0)

以下是我提出的问题:

MarioWare = {
  Tree: {
    Methods: {
      nodes: function(){
        var selected = null;
        var context = this[0];
        if (selector === undefined) // tree.nodes();
          selected = $('li', context);
        else if (typeof selector == 'string') // tree.nodes('li:first,li:last');
          selected = $(selector, context);
        else if (typeof selector == 'number') // tree.nodes(2);
          selected = $('li', context).eq(selector);
        return MarioWare.$node(selected);
      },
      appendNode: function(){...}
    }
  },
  $tree: function(selector){
    return $.extend($(selector), MarioWare.Tree.Methods);
  },
  Node: {
    Methods: {
      select: function(multiSelect) {...}
    }
  },
  $node: function(selector){
    return $.extend($(selector), MarioWare.Node.Methods);
  }
}

通过这种方式,它就像Prototype.js中的一些实用方法一样工作:

var $tree = MarioWare.$tree; //shortcut
var $node = MarioWare.$node; //shortcut
var tree = $tree('ul:first');
var nodes = tree.nodes();
nodes.eq(0).select();

它总是需要一个实用程序访问器(例如$ tree,$ node),但它会阻止jQuery名称空间受到污染。我喜欢访问者澄清我们正在使用的内容的上下文 - 例如树或节点。