如何存储一些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表示法描述的东西。
我主张使用“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插件相应地加载页面…
我发现这个元数据插件是一个很好的解决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"/>