使用jQuery的数据存储区与expando属性
我正在使用jQuery开发代码,需要存储与某些DOM元素相关的数据。 关于如何使用html元素存储任意数据还有很多其他问题,但我更感兴趣的是为什么我会选择一个选项而不是另一个。
假设为了极其简化的参数,我想存储一个“lineNumber”属性,其中每一行都是“有趣”的表。
选项1只是在每个DOM元素上设置一个expando属性(我希望我正确使用术语’expando’):
$('.interesting-line').each(function(i) { this.lineNumber = i; });
选项2是使用jQuery的data()函数将属性与元素相关联:
$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });
忽略我的示例代码的任何其他缺点,是否有充分的理由为什么您选择一种方法来存储属性而不是另一种?
如果您正在创作插件,则应使用$.data
。 如果您需要经常存储属性而很少需要查询DOM,那么请使用$.data
。
说过我所有的客户端应用程序,我倾向于在DOM元素本身上存储自定义DOM属性,以便稍后我可以使用属性 []
选择器查询它们:
var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0);
这比在每个项目上迭代包装集调用.data()
更具可读性。 我经常与另一个在DOM元素上运行的第三方库进行交互,因此通过这种机制可以快速方便地访问DOM元素,从而保持代码的可读性。
它就像存储查找表将lineNumbers
映射到元素一样简单,但是expando属性技术相比之下更不容易泄漏内存,因为您不存储稍后需要清理的DOM元素的引用。
5年后更新在收到[当之无愧的] downvote之后阅读本文:请忽略上面的标记文本。 jQuery不会根据expando属性集查询DOM,并且暂时还没有这样做。 所以使用$.data
。 当没有实用的方法时,没有理由污染DOM。
使用$.data
可以保护您免受内存泄漏的影响。
在IE中,当您将javascript对象分配给DOM元素上的expando属性时,跨该链接的循环不会被垃圾回收。 如果您的javascript对象包含对dom对象的引用,则整个循环将泄漏。 由于闭包,完全有可能最终得到对DOM对象的隐藏引用,因此您可能会在没有意识到的情况下泄漏。
设置jQuery数据存储区以防止形成这些循环。 如果使用它,就不会以这种方式泄漏内存。 您的示例不会泄漏,因为您在DOM元素上放置了原语(字符串)。 但是如果你在那里放置一个更复杂的物体,你就有泄漏的风险。
使用$.data
所以你不必担心。
使用$.data
不会修改DOM。 你应该使用$.data
。 如果您正在创建一个插件,那么您应该在$.data
存储一个对象,该对象具有该对象的属性,而不是将每个属性存储为$.data
结构中的不同键/值对。