如何存储一些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属性中(尽管这可能是因为我选择的示例不佳),但对我来说,这更有味道。是的,它在技术上是有效的,但它不是一个很好的解决方案。

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

var myData = {
link0 : {
articleId : 5,
target : '#showMessage'
// etc...
},
link1 : {
articleId : 13
}
};


<a href="..." id="link0">

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

所以,要回答这个问题,如何为HTML标签存储任意的信息?

237510 次浏览

我知道您目前正在使用jQuery,但是如果您内联定义onclick处理程序呢?然后你可以这样做:

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

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

在HTML 5中,自定义属性前缀data-是完全有效的,例如。

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

在XHTML中,这实际上是无效的。如果您使用的是XHTML 1.1模式,浏览器可能会报错,但在1.0模式下,大多数浏览器会默默地忽略它。

如果我是你,我会遵循基于脚本的方法。您可以让它在服务器端自动生成,这样维护起来就不那么麻烦了。

任意属性都是无效的,但在现代浏览器中是完全可靠的。如果您通过javascript设置属性,那么您也不必担心验证问题。

另一种方法是用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(在这里并不重要),可能有些浏览器会完全混淆,你需要检查一下。

做一些有趣的事情,比如序列化和反序列化,会更加危险。

使用ids到纯JS哈希通常是可行的,除非你试图复制你的标记。如果你有tag <a href="..." id="link0">,通过标准的JS方法复制它,然后尝试修改附加在一个副本上的data,另一个副本将被修改。

如果你不复制__abc0或使用只读数据,这不是问题。如果你复制tags并且它们被修改了,你需要手动处理。

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

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

一种可能是:

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

只是另一种方式,我个人不会使用它,但它工作(确保您的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);

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

储存:储存某物:

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

检索数据:

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

这就是它的全部内容,但请查看jQuery文档以获得更多信息/示例。

只要您的实际工作是在服务器端完成的,那么为什么还要在输出中的html标记中使用自定义信息呢?在服务器上,你所需要知道的只是一个索引,不管它是什么类型的结构列表,都包含你的自定义信息。我觉得你把信息存错地方了。

我承认,不管多么不幸,在很多情况下,正确的解决方案并不是正确的解决方案。在这种情况下,我强烈建议生成一些javascript来保存额外的信息。

许多年后:

这个问题大约是在data-...属性随着html 5的出现而成为有效选项的三年前发布的,所以真相已经发生了变化,我最初给出的答案不再相关。现在我建议改用数据属性

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


<script>
let anchors = document.getElementsByTagName('a');
for (let anchor of anchors) {
let articleId = anchor.dataset.articleId;
}
</script>

在我以前的公司,我们一直使用自定义HTML标记来保存表单元素的信息。问题在于:我们知道用户被迫使用IE。

当时它在FireFox上运行得并不好。我不知道FireFox是否改变了这一点,但是请注意,读者的浏览器可能支持也可能不支持向HTML元素添加自己的属性。

如果你可以控制你的阅读器使用的浏览器(例如,一个公司的内部web applet),那么无论如何都要尝试一下。这又有什么坏处,对吧?

作为jQuery用户,我将使用插件元数据。HTML看起来很干净,可以进行验证,并且可以嵌入任何可以使用JSON符号描述的内容。

我提倡使用“rel”属性。XHTML进行验证,很少使用属性本身,并且可以有效地检索数据。

所以应该有四种选择:

  1. 将数据放在id属性中。
  2. 将数据放在任意属性中
  3. 将数据放在class属性中
  4. 将数据放在另一个标记中

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

这就是我怎么做你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被关闭了,那么url就会像往常一样…所有“应用程序”(网站的每个部分)都有自己的关键字……所以我所需要做的就是添加到js数组上面添加更多的页面…

例如,我的当前设置设置为:

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

因此,如果我有一个url,如:

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

js脚本将取代/ads/部分,所以我的URL将结束

www.domain.com/ads/ p = 3923 /爸爸/ bla bla

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

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

我发现元数据插件可以很好地解决使用html标记存储任意数据的问题,并且可以很容易地检索和使用jQuery。

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

下面是一个例子,它被用来存储值时,我使用生成谷歌分析跟踪事件(注:数据。标签和数据。值碰巧是可选参数)

$(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"/>

这是个好建议。感谢@Prestaul

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

非常正确,但是如果您想在普通的HTML中存储任意数据呢?还有另一种选择……

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

将数据放在隐藏输入元素的name和value属性中。如果服务器正在生成HTML(即PHP脚本或其他东西),而您的JavaScript代码稍后将使用此信息,那么这可能是有用的。

不可否认,它不是最干净的,但它是一种选择。它与所有设备都兼容 浏览器,是有效的XHTML。应该使用自定义属性,也不应该使用带有'data-'前缀的属性,因为它可能不适用于所有浏览器。此外,您的文档将无法通过W3C验证

另一种方法是将key:value对存储为一个简单的类,使用以下语法:

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

这是有效的,可以很容易地用jQuery选择器或自定义函数检索。

您可以使用隐藏的输入标记。我在w3.org上没有得到验证错误:

<!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,你会得到文章ID类似(未测试):

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

但如果可以的话,我会推荐HTML5。

你可以使用你自己的随机元素属性(<span data-randomname="Data goes here..."></span>)的data-前缀,但这只在HTML5中有效。因此,浏览器可能会抱怨有效性问题。

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

但我个人更喜欢的是:

<input type="hidden" title="Your key..." value="Your value..." />
输入在所有情况下都将被隐藏,属性是完全有效的,如果它在<form>标记中,它将不会被发送,因为它没有任何名称,对吗? 最重要的是,属性真的很容易记住,代码看起来很漂亮,很容易理解。你甚至可以在它里面放一个id属性,这样你也可以很容易地用JavaScript访问它,并使用input.title; input.value访问键值对

使用jquery,

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

返回:$('#element_id').data('extra_tag');

在html中,我们可以存储自定义属性,在属性名之前加上“data-”前缀

< p > <p data-animal='dog'>This animal is a dog.</p>。 检查文档 < / p > 我们可以使用这个属性动态设置和获取属性使用jQuery,如: 如果我们有一个p标签,如

<p id='animal'>This animal is a dog.</p>

然后为上面的标签创建一个名为'breed'的属性,我们可以这样写:

$('#animal').attr('data-breed', 'pug');

为了随时检索数据,我们可以这样写:

var breedtype = $('#animal').data('breed');

我的回答可能不适用于你的情况。我需要在HTML中存储一个2D表,并且我需要用最少的按键操作。下面是我的HTML数据:

<span hidden id="my-data">
IMG,,LINK,,CAPTION
mypic.jpg,,khangssite.com,,Khang Le
funnypic.jpg,,samssite.com,,Smith, Sam
sadpic.png,,joyssite.com,,Joy Jones
sue.jpg,,suessite.com,,Sue Sneed
dog.jpg,,dogssite.com,,Brown Dog
cat.jpg,,catssite.com,,Black Cat
</span>

解释

  • 它使用隐藏属性隐藏。不需要CSS。
  • 这是由Javascript处理的。我使用了两个分割语句,第一个在换行符上,然后在双逗号分隔符上。这就把整个东西放到了一个2D数组中。
  • 我想尽量减少打字。我不想重复键入每一行的字段名(json/jso风格),所以我只是把字段名放在第一行。这对程序员来说是一个可视的键,Javascript也用它来知道字段名。我去掉了所有的大括号,等号,双括号等等。行尾是记录分隔符。
  • 我使用双逗号作为分隔符。我想没有人会在任何事情上使用双逗号,而且它们很容易输入。注意,程序员必须为任何空单元格输入空格,以防止意外的双逗号。程序员可以很容易地使用不同的分隔符,只要他们更新Javascript。如果确定单元格中没有嵌入逗号,则可以使用单逗号。
  • 这是一个span,以确保它不占用页面上的空间。

下面是Javascript代码:

// pull 2D text-data into array
let sRawData = document.querySelector("#my-data").innerHTML.trim();


// get headers from first row of data and load to array. Trim and split.
const headersEnd = sRawData.indexOf("\n");
const headers = sRawData.slice(0, headersEnd).trim().split(",,");


// load remaining rows to array. Trim and split.
const aRows = sRawData.slice(headersEnd).trim().split("\n");


// trim and split columns
const data = aRows.map((element) => {
return element.trim().split(",,");
});

解释:

  • JS使用大量的修饰来消除任何额外的空白。