【问题标题】:Best plugin development practices to avoid polluting jQuery namespace?避免污染 jQuery 命名空间的最佳插件开发实践?
【发布时间】:2010-12-22 02:02:32
【问题描述】:

我创建了一个 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.

在不污染 jQuery 命名空间的情况下,将接口暴露给已激活的 DOM 元素及其子元素有哪些做法?

我玩过保存创建树时返回的 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()

你如何处理这个问题?你能指出一些现有的插件来解决这个问题,我可以从他们的代码中学习吗?

【问题讨论】:

    标签: jquery jquery-plugins namespaces


    【解决方案1】:

    使用简短明了的名称!不是无聊的tree,而是例如nicetree(嘿,这只是一个想法)!将接口放入名称中。像这样:

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

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

    作为插件用户,我喜欢这两种解决方案,但更喜欢第一种。

    【讨论】:

    • 我见过这种方法并且喜欢它。但是,正如我输入的答案所示,我已经解决了一些问题。
    • appendNode() 或 item() 方法如何引用包含选定元素的 jQuery 对象(在本例中为 $("ol#tree"))?似乎它遇到的问题是,这些函数中的“this”并没有带你回到足够远的地方找到 jQuery 对象,只是 nicetree 对象,它是一个从 jQuery 原型创建的静态对象。
    【解决方案2】:

    这是我提出的问题:

    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 命名空间被污染。我喜欢访问器阐明我们正在使用的内容的上下文——例如树或节点。

    【讨论】:

    • 为此,所有返回值都必须使用适当的实用方法重新包装结果。例如“select”将返回“$node(result)”。我还必须重写基本的 jQuery 函数(如“eq”)以返回包装的结果。啊!有点笨拙——但它有效。
    猜你喜欢
    • 2015-03-05
    • 2011-05-14
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多