【问题标题】:jQuerys $.data() vs. DOM Object propertyjQuery $.data() 与 DOM 对象属性
【发布时间】:2010-08-04 16:28:39
【问题描述】:

我最近需要将一些数据附加到动态创建的LI elements。在我的第一个例子中,我使用.data() 的方式类似于

var _newli = $('<li>foobar</li>');
_newli.data('base', 'ball');
// append _newli to an `ul`

那.. 非常慢。这个逻辑发生在一个可以轻松增长到 500 多个项目的循环中,这需要很长时间!有时它甚至打破了 javascript 的执行时间框架。

于是我改成了$.data()。不知何故,将数据附加到对象上比通过.data() 方法调用快8x。所以现在看起来像

var _newli = $('<li>foobar</li>');
$.data(_newli[0], 'base', 'ball');
// append _newli to an `ul`

这确实/确实更快,但构建所有元素仍然需要 3-4 秒(!)(在我的真实代码中,每个元素大约有 6 次 $.data 调用)。

所以我真的被困住了,我问自己为什么要使用.data()$.data()?我可以将我的数据附加到DOM object。所以我做到了

var _newli = $('<li>foobar</li>');
_newli[0].base = 'ball';
// append _newli to an `ul`

瞧,令我震惊,这真是太快了!我简直不敢相信它跑得这么好,没有任何劣势。这就是我的问题所在。到目前为止,我在网上没有发现这种技术有任何缺点。有关于您可以使用这种方式创建的循环引用的阅读,但 AFAIK“仅”在 IE 上且仅当您引用 objects 时。

任何想法专家?

更新

感谢优秀的 cmets 和帖子。简短更新@patrick dw:

你是对的,我在使用$.data() 时传递了底层DOM element。它甚至不适用于 jQuery 对象,至少不像预期的那样。 关于使用一个对象并通过$.date() 传递它的想法我有自己的想法,但是我再次对性能差异感到非常震惊,我决定永远忽略.data() 方法。

【问题讨论】:

  • 如果有 "每个元素对 $.data 进行 6 次调用",您是否有理由不只进行一次调用,而是为包含您想要的所有属性的值? $.data(_newli,'myvalues',{'base':'ball','basket':'ball','foot':'ball'});
  • 在一次谈话中,约翰说它很慢,并建议做var data = $('selector').data(); data['foo'] = 'bar'; data['bar'] = 'foo'; etc.,这样你就只有一个访问它。仅供参考。
  • @jAndy - 您应该将 DOM 元素传递给 $.data()。不是jQuery 对象。我想知道这是否也会对性能产生影响。 $.data(_newli[0], 'base', 'ball');
  • @patrick dw:更新了帖子! @Felix Kling:听起来很合理,你知道我在哪里可以找到 Resig 演讲/论文吗?无论如何我都会试一试,最大的问题是,DOM property storage 是否接近?否则无论如何它都毫无用处。
  • jAndy - 我使用 Webkit 的配置文件工具做了几个配置文件,使用 @Felix 的解决方案与写入 DOM 元素,分配 one 属性。 如果我在测试中不包括初始变量赋值数据:0.025ms,DOM:0.040ms。如果我确实包含了 data()var data = $.data(_newli[0]) 的变量赋值,它会在 data: 0.040ms 到 0.225ms 之间变化。但这是为了分配一个属性。分配几个属性将缩小一些差距(当它存在时)。在 500 个元素上使用 $.data(),其最慢的时间约为 22 毫秒。相当快。同样,这只是 Webkit。

标签: javascript jquery html dom


【解决方案1】:

循环引用是正确的,这在 IE 之外不是问题,而在 IE 中,只有当 JavaScript 引用 DOM 对象并且 JS 对象是分配给 DOM 对象的属性之一。我相信这可以通过简单地通过取消 JS 中对 DOM 对象的任何引用来解决。

$().data() 方法是 $.data() 的一个过于复杂的包装器(请参阅 jQuery.fn.data:http://github.com/jquery/jquery/blob/master/src/data.js#L126,它又调用 jQuery.data:http://github.com/jquery/jquery/blob/master/src/data.js#L20),所以去掉中间人将节省一个非微不足道的时间,特别是如果要完成 500 次。

在这种情况下,$().data('foo', 'bar') 方法的作用并不比el.foo = 'bar' 多。做最快的事。

【讨论】:

    【解决方案2】:

    当尝试向 NodeList 对象添加自定义属性时,浏览器 (IE) 可能不允许这样做。见:http://lists.w3.org/Archives/Public/public-webapps/2010JanMar/0864.html

    【讨论】:

      【解决方案3】:

      这些可能会有所帮助:

      并阅读以下关于使用自定义 DTD 的内容:

      简而言之,在大多数情况下,我认为使用自定义属性不会遇到任何问题。大多数明智/当前的浏览器都可以使用它。我会说,我确实遇到了我为 MobileSafari 开发的 web 应用程序的问题,这迫使我求助于使用 $.data 隐藏元素。幸运的是,我没有 500 多个元素,但更多的是五六个。

      【讨论】:

      • 我想我们在谈论两个不同的故事。如果您将一些数据附加到element.somedata = {foo: 5};,则不会为此创建attribute。这就像以某种方式混合 ECMAlandDOMland,因为 DOM element 在 ECMAscript 中被视为对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      相关资源
      最近更新 更多