有时我想将某种元数据附加到HTML节点上,我想知道,最好的方法是什么。
我可以想象以下内容:
<div myattr1="myvalue1" myattr2="myvalue2" >
(中断验证)<div class="myattr1-myvalue2-myattr2-myvalue2">
(需要解析和某种程度的转义)这两种解决方案都非常难看!
有没有办法更优雅地做到这一点?我已经在使用jQuery,所以任何好的Javascript解决方案,如果有的话,也会受到赞赏。
答案 0 :(得分:37)
HTML5引入了custom data attributes的概念,任何人都可以创建这个概念,以便将自定义隐藏数据附加到元素以用于编写脚本。只需使用data-
前缀(例如data-myattr1
或data-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
个type
个元素以及text/javascript
以外的其他属性(或者一个其中一些可用于指定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>
这是SVG Web允许在HTML中嵌入SVG的技术,如果浏览器不支持本机SVG,则通过Flash进行模拟。目前,即使支持SVG(Firefox,Safari,Chrome,Opera)的浏览器也不支持直接内联在HTML中,它们只支持在XHTML中直接内联(因为SVG元素位于不同的命名空间中)。 SVG Web允许您使用脚本标记将SVG内联到HTML中,然后将这些元素转换为适当的命名空间并将它们添加到DOM中,以便将它们呈现为XHTML。在不支持SVG的浏览器中,它还使用Flash模拟元素的功能。
答案 1 :(得分:11)
如果没有必要在标记中存储属性,那么一个很好的解决方案是jQuery的data
函数:http://docs.jquery.com/Core/data。
答案 2 :(得分: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
答案 3 :(得分:3)
假设XHTML,只需为您自己的元数据引入一个新的命名空间。这样,您可以使用任意名称在自己的命名空间中拥有属性,并且它们不会与任何验证冲突。
基本上你只需要添加
xmlns:myns="http://www.example.com/URI/to/myNamespaceDeclaration"
到根节点,然后你可以拥有诸如
之类的节点<p myns:type="important">I'm a paragraph.</p>
在那个根目录下的任何地方。这基本上是命名空间的全部目的,允许开发人员将任意数据作为层添加到整个模型中。
修改强>
快速注释,class
属性现在被microformats用于元数据标记目的。您可能需要查看上面的链接,看看是否有人已经发明了您想要提出的方向盘:)
答案 4 :(得分:2)
WeakMap可能会做到这一点。它是一个类似于地图的数据结构,其中键是对象,值是任意值。
const div = document.createElement("div")
const metadata = new WeakMap()
metadata.set(div, "div metadata")
metadata.get(div) // "div metadata"
答案 5 :(得分:0)
如果你正在使用xhtml,你可以调整你的DTD,以便你的额外属性验证。
如果您使用的是html5,则可以使用data-foobarbaz属性。