如何存储一些HTML标签的任意数据

我正在做一个由JavaScript提供一些交互的页面。 举个例子:发送AJAX请求获取文章内容然后在div中显示该数据的链接。 显然在这个例子中,我需要每个链接来存储额外的信息:文章的ID。 我一直在处理它的方式是把这些信息放在这个href链接里:

<a class="article" href="#5"> 

然后,我使用jQuery来查找a.article元素并附加适当的事件处理程序。 (不要太在意这里的可用性或语义,这只是一个例子)

无论如何,这个方法是有效的,但它有点味道 ,而且根本不可扩展(如果click函数有多个参数,会发生什么情况?如果其中一些参数是可选的呢?)

立即明显的答案是使用元素的属性。 我的意思是,这就是他们的目的,对吧? (有点)。

 <a articleid="5" href="link/for/non-js-users.html"> 

在我最近的问题中,我问了这个方法是否有效,结果是我没有定义我自己的DTD(我没有),那么不是,它是无效的或可靠的。 一个普遍的回答是把数据放入class属性中(尽pipe这可能是因为我的select不好),但是对我来说,这个味道更大。 是的,这在技术上是有效的,但这不是一个好的解决scheme。

过去使用的另一种方法是实际生成一些JS,并将其插入到<script>标记的页面中,创build一个与该对象关联的结构。

 var myData = { link0 : { articleId : 5, target : '#showMessage' // etc... }, link1 : { articleId : 13 } }; <a href="..." id="link0"> 

但是,这可能是一个真正的屁股维护的痛苦,通常只是非常混乱。

所以,为了解决这个问题, 你如何为HTML标签存储任意信息

您使用的是哪个版本的HTML?

在HTML 5中, 以数据为前缀的自定义属性是完全有效的,例如

 <div data-internalid="1337"></div> 

在XHTML中,这不是真的有效。 如果您使用的是XHTML 1.1模式,那么浏览器可能会抱怨,但在1.0模式下,大多数浏览器都会默默地忽略它。

如果我是你,我会遵循脚本的方法。 你可以让它在服务器端自动生成,所以在后面维护并不痛苦。

如果你已经使用jQuery,那么你应该利用“数据”方法,这是推荐的方法,用jQuery在dom元素上存储任意数据。

存储的东西:

 $('#myElId').data('nameYourData', { foo: 'bar' }); 

要检索数据:

 var myData = $('#myElId').data('nameYourData'); 

这就是所有这一切,但看看更多的信息/例子的jQuery文档 。

另一种方法,我个人不会使用这个,但它的作品(保证你的JSON是有效的,因为eval()是危险的)。

 <a class="article" href="link/for/non-js-users.html"> <span style="display: none;">{"id": 1, "title":"Something"}</span> Text of Link </a> // javascript var article = document.getElementsByClassName("article")[0]; var data = eval(article.childNodes[0].innerHTML); 

任意属性无效,但在现代浏览器中完全可靠。 如果你通过javascript设置属性,那么你也不用担心validation。

另一种方法是在JavaScript中设置属性。 jQuery有一个很好的实用方法,只是为了这个目的,或者你可以推出自己的。

几乎所有可能的浏览器都可以使用的破解方法是使用这样的开放类: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

对于纯粹主义者来说,这并不是那么优雅,但它是普遍支持的,符合标准并且很容易操作。 这真的好像是最好的方法。 如果您serialize修改复制您的标签,或做其他任何事情, data将保持附加,复制等。

唯一的问题是,你不能以这种方式存储不可序列化的对象,如果你在那里放了一些非常大的东西,可能会有限制。

第二种方法是使用假的属性,如: <a articleid='5' href="link/for/non-js-users.html">

这更优雅,但打破标准,我不是100%肯定的支持。 许多浏览器都支持它,我认为IE6支持JS访问,但不支持CSS selectors (在这里并不重要),也许有些浏览器会完全混淆,你需要检查它。

做序列化和反序列化等有趣的事情会更危险。

除了当您尝试复制您的标签时,使用纯JS散列的ids大多工作。 如果你有tag <a href="..." id="link0"> ,通过标准的JS方法复制它,然后尝试修改只附加到一个副本的data ,另一个副本将被修改。

如果您不复制tag或使用只读数据,这不是问题。 如果您复制tag并修改了tag ,则需要手动处理。

我知道你目前正在使用jQuery,但是如果你定义了onclick处理程序内联。 那么你可以这样做:

  <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'> Article 5</a> 

你可以使用隐藏的input标签。 我在w3.org没有得到validation错误:

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'> <head> <meta content="text/html;charset=UTF-8" http-equiv="content-type" /> <title>Hello</title> </head> <body> <div> <a class="article" href="link/for/non-js-users.html"> <input style="display: none" name="articleid" type="hidden" value="5" /> </a> </div> </body> </html> 

使用jQuery,您可以使用类似于(未testing)的文章ID:

 $('.article input[name=articleid]').val(); 

但是我build议HTML5,如果这是一个选项。

使用jQuery,

存储: $('#element_id').data('extra_tag', 'extra_info');

检索: $('#element_id').data('extra_tag');

为什么不利用已经存在的有意义的数据,而不是添加任意的数据?

即使用<a href="/articles/5/page-title" class="article-link"> ,然后你可以以编程方式获取页面上的所有文章链接(通过类名)和文章ID(匹配正则expression式/articles\/(\d+)/ against this.href )。

作为一个jQuery用户,我会使用元数据插件 。 HTML看起来很干净,它可以validation,并且可以embedded任何可以使用JSON表示法描述的东西。

所以应该有四个select:

  1. 把数据放在id属性中。
  2. 把数据放在任意属性中
  3. 把数据放在class属性中
  4. 把你的数据放在另一个标签

http://www.shanison.com/?p=321

我主张使用“rel”属性。 XHTMLvalidation,属性本身很less使用,数据被有效地检索。

这是个好build议。 感谢@Prestaul

如果你已经使用jQuery,那么你应该利用“数据”方法,这是推荐的方法,用jQuery在dom元素上存储任意数据。

非常真实的,但是如果你想要在普通的HTML中存储任意的数据呢? 这是又一个select…

 <input type="hidden" name="whatever" value="foobar"/> 

把你的数据放在一个隐藏的input元素的name和value属性中。 这可能是有用的,如果服务器生成的HTML(即PHP脚本或其他),你的JavaScript代码将在稍后使用这些信息。

诚然,不是最干净的,但它是一个select。 它与所有浏览器兼容,并且是有效的XHTML。 您不应该使用自定义属性,也不应该使用“data-”前缀属性,因为它可能不适用于所有浏览器。 此外,您的文档将不会通过W3Cvalidation。

另一种方法是使用以下语法将键值对存储为简单的类:

 <div id="my_div" class="foo:'bar'">...</div> 

这是有效的,可以很容易地检索与jQueryselect器或自定义function。

您可以使用随机元素的自定义属性的数据前缀( <span data-randomname="Data goes here..."></span> ),但是这仅在HTML5中有效。 因此浏览器可能会抱怨有效性。

您也可以使用<span style="display: none;">Data goes here...</span>标记。 但是这样你就不能使用属性函数,如果closures了css和js,这也不是一个很好的解决scheme。

但我个人更喜欢以下内容:

 <input type="hidden" title="Your key..." value="Your value..." /> 

input将在所有情况下被隐藏,属性是完全有效的,如果它在<form>标签内,它将不会被发送,因为它没有任何名字,对吗? 最重要的是,这些属性非常容易记住,代码看起来不错,易于理解。 你甚至可以在其中放入一个ID属性,所以你可以很容易地用JavaScript访问它,并且用input.title; input.value访问键值对input.title; input.value input.title; input.value

一种可能性可能是:

  • 创build一个新的div来保存所有的扩展/任意数据
  • 做一些事情,以确保这个div是不可见的(例如,CSS加上div的class属性)
  • 将扩展/任意数据放置在这个不可见的div中的[X] HTML标签(例如表格单元格内的文本,或其他任何你可能喜欢的)中

只要你真正的工作是在服务器端完成,为什么你需要输出html标签中的自定义信息呢? 所有你需要知道的服务器是一个索引到你的自定义信息的任何types的结构列表。 我想你想把信息存储在错误的地方。

无论如何,我将认识到,在许多情况下,正确的解决scheme并不是正确的解决scheme。 在这种情况下,我强烈build议生成一些JavaScript来保存额外的信息。

在我以前的雇主中,我们一直使用自定义的HTML标签来保存有关表单元素的信息。 问题:我们知道用户被迫使用IE。

当时对FireFox来说效果并不好。 我不知道FireFox是否改变了这一点,但是请注意,将自己的属性添加到HTML元素可能会或可能不会被读者的浏览器支持。

如果你可以控制你的读者正在使用哪个浏览器(例如一个公司的内部web小应用程序),那么试一试吧。 有什么可伤害的,对吧?

这就是我如何做你的Ajax页面…这是一个非常简单的方法…

  function ajax_urls() { var objApps= ['ads','user']; $("a.ajx").each(function(){ var url = $(this).attr('href'); for ( var i=0;i< objApps.length;i++ ) { if (url.indexOf("/"+objApps[i]+"/")>-1) { $(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p=")); } } }); } 

这是如何工作的,它基本上查看所有的类有'ajx'的url,它取代了一个关键字,并添加了#号…所以如果js被closures,那么这些url就像通常那样运行……所有的“应用程序“(网站的每个部分)都有自己的关键字…所以我只需要添加到上面的js数组添加更多的页面…

所以例如我目前的设置设置为:

  var objApps= ['ads','user']; 

所以如果我有一个url如:

http://www.domain.com/ads/3923/bla/dada/bla

该js脚本将取代/广告/部分,所以我的url将最终成为

http://www.domain.com/ads/#p=3923/bla/dada/bla

然后,我使用jquery bbq插件相应地加载页面…

http://benalman.com/projects/jquery-bbq-plugin/

我发现这个元数据插件是一个很好的解决scheme,用html标签存储任意数据的问题,这样可以很容易地用jQuery进行检索和使用。

重要提示 :您包含的实际文件只有5 kb,而不是37 kb(这是完整下载包的大小)

这是一个用来存储我在生成谷歌分析跟踪事件时使用的值的例子(注意:data.label和data.value碰巧是可选的参数)

 $(function () { $.each($(".ga-event"), function (index, value) { $(value).click(function () { var data = $(value).metadata(); if (data.label && data.value) { _gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]); } else if (data.label) { _gaq.push(['_trackEvent', data.category, data.action, data.label]); } else { _gaq.push(['_trackEvent', data.category, data.action]); } }); }); }); <input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>