2010-01-09 144 views
24

有时我想附加一些元数据到HTML节点,我想知道,做这件事的最好方法是什么。如何将“元数据”附加到DOM节点?

我能想象以下:

  • 非标准属性:<div myattr1="myvalue1" myattr2="myvalue2" >(符验证)
  • 重新使用现有的属性<div class="myattr1-myvalue2-myattr2-myvalue2">(需要解析和逸出的一些电平)

这两种解决方案真的很难看!

有没有办法更优雅地做到这一点?我已经在使用jQuery,所以任何好的Javascript解决方案,如果有的话,也表示赞赏。

回答

11

如果没有必要在标记中存储属性,一个很好的解决方案是jQuery的data函数:http://docs.jquery.com/Core/data

+0

直到HTML变得普遍,我认为这是最好的解决方案。 – 2010-01-30 23:07:56

+5

我的意思是“HTML 5”,当然:) – 2011-01-14 12:45:03

+0

有没有一个标准的方法来做到这一点,而没有jQuery在现代的JavaScript? – TKoL 2017-10-20 13:57:41

0

如果你使用xhtml,你可以调整你的DTD,这样你的额外属性就可以验证了。

如果您使用的是html5,则可以使用data-foobarbaz属性。

5

一个可能的解决方案可能并不完全符合您的要求,即将一个类用作“元数据存储库”,并使用方法根据元素的ID获取/设置数据。

var metadataRepository = function(){ 
    this.elements = []; 

    this.set = function(id,key,value){ 
     this.elements[id][key] = value; 
    } 

    this.get = function(id,key){ 
     if (typeof(this.elements[id]) == "undefined"){ 
      return null; 
     } 
     if (key){ 
      return (this.elements[id][key] != "undefined") ? this.elements[id][key] : null; 
     } else { 
      return this.elements[id]; 
     } 
    } 

} 

var myMR = new metadataRepository(); 

myMR.set("myDiv1","attr1",232442); 
myMR.set("myDiv2","attr1",{"id":23,"name":"testName"}); 

... 

myMR.get("myDiv1","attr1"); //Returns only attr1 
myMR.get("myDiv2"); //Returns all attributes 
+0

浩浩,我知道,两年后,但无论如何感谢你分享@amercader – 2012-06-03 05:47:29

+0

@JoshGuzman你不认为你是唯一一个问这个问题吗? – Yaroslav 2018-02-21 02:45:00

35

HTML5引入的custom data attributes的概念,任何人都可以以定制的,隐性数据附加到脚本编写方面的元素创建。只需使用data-前缀(例如data-myattr1data-myattr2)创建属性,并将其填入数据。

<div data-myattr1="myvalue1" data-myattr2="myvalue2">Content</div> 

这个解决方案的好处是它已经可以在所有主流浏览器中使用了;他们将全部解析未知属性,并将它们暴露在DOM中供JavaScript访问。 HTML5增加了一些访问它们的便捷机制,但尚未实现,但您现在可以使用标准getAttribute来访问它们。事实上,他们在HTML5中是允许的,这意味着只要您愿意使用标准草案而不是已接受的标准(我不认为data-属性特别具有争议性,那么您的代码就会被验证),所以如果他们从标准中删除,我会感到惊讶)。

优势这已超过在XHTML命名空间的属性是IE不支持XHTML,那么你就必须实现的东西,假装要使用名称空间的属性,但实际上只使用了:无效的属性在他们的名字,这是IE将如何解析它们。这比使用class更好,因为将大量数据放入class属性中会使其重复很多,并且需要执行额外的解析来提取不同的数据。并且它比自己制作(可以在当前浏览器中工作)要好,因为它明确地定义了以data-为前缀的这些属性是用于编写脚本的私有数据片段,因此您的代码将在HTML5中进行验证,并且永远不会发生冲突与未来的标准。

用于添加自定义数据为HTML,这是有效的,即使在HTML 4中,加入script元件具有比text/javascript(或可用于将几个其他类型中的一种以外的东西type属性的另一种鲜为人知的技术指定JavaScript)。这些脚本块将被不知道如何与它们配合的浏览器忽略,您可以通过DOM访问它们并按照自己的意愿进行操作。 HTML5 explicitly discusses this usage,但没有什么能够让它在旧版本中无效,并且据我所知,它适用于所有现代浏览器。例如,如果你想使用CSV来定义数据表:

<div> 
    <script type="text/csv;header=present"> 
    id,myattr1,myattr2 
    something,1,2 
    another,2,4 
    </script> 
    Content 
</div> 

这是通过Flash使用SVG Web允许SVG的嵌入在HTML中,与仿真如果浏览器不支持该技术本地SVG。目前,即使支持SVG(Firefox,Safari,Chrome,Opera)的浏览器也不直接以HTML格式支持它,它们只支持直接以XHTML内联(因为SVG元素位于不同的名称空间中)。 SVG Web允许您使用脚本标记将SVG内联到HTML中,然后将这些元素转换为适当的名称空间并将它们添加到DOM,以便它们可以呈现为XHTML。在不支持SVG的浏览器中,它还使用Flash模拟元素的功能。

3

假设XHTML,只需为您自己的元数据引入一个新的名称空间。这样你可以在自己的名字空间中拥有任意名称的属性,并且它们不会与任何验证冲突。

基本上所有你需要的是

xmlns:myns="http://www.example.com/URI/to/myNamespaceDeclaration" 

添加到根节点,然后你可以有诸如

<p myns:type="important">I'm a paragraph.</p> 

下是根任何地方的节点。这基本上是命名空间的全部目的,允许开发人员将任意数据作为图层添加到整个模型中。

编辑:

而且快速注意到,class属性是时下使用了大量的microformats为元数据标记目的。你可能想看看上面的链接,看看是否有人已经发明了你想要拿出来的车轮:)

0

WeakMap可能会伎俩。它是一个类似于地图的数据结构,其中键是对象,值是任意值。

const div = document.createElement("div") 
const metadata = new WeakMap() 
metadata.set(div, "div metadata") 
metadata.get(div) // "div metadata"