大规模jQuery选择器缓存

时间:2013-02-27 16:16:37

标签: javascript jquery performance

哪些模式可用于在大型JavaScript应用程序中缓存许多jQuery选择器以便重复使用?

关于在简单函数中的简单变量中存储jQuery选择器有很多说法,但在JavaScript对象中,例如在流行的模块模式中,如何干净地设置和存储它们?

我最初的尝试是使用全局变量,但这会弄脏命名空间并可能导致冲突。我的第二次尝试涉及将选择器存储在相应对象内的对象文字中,但这会导致对它们的调用时间长于所需,例如:

var Module = {

  nodes: {},

  storeSelectorsInCache: function() {
    Module.nodes = {
      form: $('#form'),
      grid: $('#grid')
    };
  },

  initialize: function() {
    Module.storeSelectorsInCache();

    // notice the long hierarchy to get to Module.nodes.form
    Module.nodes.form.submit(function() {
      // event handler
    });
  }

};

某处必须有一个更清洁的速记。

1 个答案:

答案 0 :(得分:4)

这样的事情可能很酷:

var _nodes = {};

var Module = {
  /**
   * You could call this when you want to query a selector and store it for reuse. Then 
   * just use this for querying.
   * 
   * @param {String} selector The selector to memoize.
   * @param forceUpdate {Boolean} jQuery selectors don't update with their DOM 
   *     counterparts. This will take that into account. Pass in true to override cache.
   *
   * @return {Object<Array<jQuery>>} The matching selectors.
   */
  $: function(selector, forceUpdate) {
    if (forceUpdate === true || !({}).hasOwnProperty.call(_nodes, selector)) {
      _nodes[selector] = jQuery(selector); // Not that robust, just a basic example
    }
    return _nodes[selector];
  },

  initialize: function() {
    this.$('#form').submit(function () { /* ... */ });
  }
};

因此,每当您使用本地范围的Module.$函数查询选择器时,它会将结果缓存在节点对象中(此处将被用作关联数组)。但是,如果节点对象中没有该选择器的结果,那么它将查询DOM。此外,还有一个额外的参数可以强制更新nodes中的选择器。

或者你可以使用lodash的memoize函数,如下所示:

// inside your Module
$: _.memoize(jQuery);