提问人:nickf 提问时间:1/11/2009 最后编辑:Communitynickf 更新时间:11/16/2022 访问量:246094
如何存储某些 HTML 标记的任意数据
How to store arbitrary data for some HTML tags
问:
我正在制作一个页面,其中包含 javascript 提供的一些交互。举个例子:发送 AJAX 请求以获取文章内容的链接,然后在 div 中显示该数据。显然,在这个例子中,我需要每个链接来存储额外的信息:文章的 ID。我一直在处理它的方式是将该信息放在 href 链接中:
<a class="article" href="#5">
然后,我使用 jQuery 查找 a.article 元素并附加相应的事件处理程序。(不要太执着于这里的可用性或语义,这只是一个例子)
无论如何,这个方法有效,但它有点臭,而且根本不可扩展(如果点击函数有多个参数,会发生什么情况?如果其中一些参数是可选的呢?
显而易见的答案是在元素上使用属性。我的意思是,这就是他们的目的,对吧?(有点)。
<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标签的任意信息?
答:
我知道您目前正在使用 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 模式下,大多数浏览器会默默地忽略它。
如果我是你,我会遵循基于脚本的方法。你可以让它在服务器端自动生成,这样维护起来就不麻烦了。
评论
$(this).data('internalid');
$(this).data('data-internalid');
任意属性是无效的,但在现代浏览器中是完全可靠的。如果您通过 javascript 设置属性,那么您也不必担心验证。
另一种方法是在 javascript 中设置属性。jQuery有一个很好的实用方法,或者你可以推出自己的方法。
评论
data-
一个几乎可以与所有可能的浏览器一起使用的技巧是使用这样的开放类:<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
如果您不复制 s 或使用只读数据,这不是问题。如果您复制了 s 并且它们被修改了,则需要手动处理。tag
tag
评论
为什么不利用已经存在的有意义的数据,而不是添加任意数据呢?
即使用 ,然后您可以以编程方式获取页面上的所有文章链接(通过类名)和文章 ID(与正则表达式匹配)。<a href="/articles/5/page-title" class="article-link">
/articles\/(\d+)/
this.href
评论
一种可能性可能是:
- 创建一个新 div 来保存所有扩展/任意数据
- 做一些事情来确保这个div是不可见的(例如.CSS加上div的类属性)
- 将扩展/任意数据放在 [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来保存额外的信息。
许多年后:
这个问题是在属性成为 html 5 出现有效选项之前大约三年发布的,所以事实已经发生了变化,我给出的原始答案不再相关。现在我建议改用数据属性。data-...
<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 元素可能会也可能不会被读者的浏览器支持。
如果您可以控制您的读者正在使用哪个浏览器(即公司的内部网络小程序),那么请务必尝试一下。它能伤害什么,对吧?
作为jQuery用户,我会使用元数据插件。HTML 看起来很干净,可以验证,并且您可以嵌入任何可以使用 JSON 表示法描述的内容。
我主张使用“rel”属性。XHTML 进行验证,很少使用属性本身,并且有效地检索数据。
评论
因此,应该有四种选择:
- 将数据放在 id 属性中。
- 将数据放在任意属性中
- 将数据放在 class 属性中
- 将您的数据放入其他代码中
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'];
因此,如果我有一个网址,例如:
www.domain.com/ads/3923/bla/dada/bla
js 脚本将替换 /ads/ 部分,因此我的 URL 最终会成为
www.domain.com/ads/#p=3923/bla/dada/bla
然后我使用 jquery bbq 插件相应地加载页面......
http://benalman.com/projects/jquery-bbq-plugin/
我发现元数据插件是解决使用 html 标签存储任意数据问题的绝佳解决方案,使其易于检索和使用 jQuery。
重要提示:您包含的实际文件只有 5 kb,而不是 37 kb(这是完整下载包的大小)
下面是一个示例,它用于存储我在生成 google analytics 跟踪事件时使用的值(注意: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"/>
这是一个很好的建议。感谢@Prestaul
如果你已经在使用jQuery,那么你应该利用“数据” 方法,这是在 dom 元素替换为 jQuery。
非常正确,但是如果您想将任意数据存储在普通的 HTML 中怎么办?这是另一种选择......
<input type="hidden" name="whatever" value="foobar"/>
将数据放在隐藏输入元素的 name 和 value 属性中。如果服务器正在生成 HTML(即 PHP 脚本或其他),并且您的 JavaScript 代码稍后将使用此信息,这可能很有用。
诚然,不是最干净的,但它是一种选择。它与所有 浏览器,并且是有效的 XHTML。您不应该使用自定义属性,也不应该真正使用带有“data-”前缀的属性,因为它可能不适用于所有浏览器。此外,您的文档将无法通过 W3C 验证。
评论
另一种方法是使用以下语法将键值对存储为简单类:
<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。
评论
style="display: none"
您可以使用自己的随机元素 () 的 made 属性的 data- 前缀,但这仅在 HTML5 中有效。因此,浏览器可能会抱怨有效性。<span data-randomname="Data goes here..."></span>
您也可以使用标签。但是这样你就不能使用属性函数了,如果关闭了css和js,这也不是一个真正的解决方案。<span style="display: none;">Data goes here...</span>
但我个人更喜欢以下几点:
<input type="hidden" title="Your key..." value="Your value..." />
输入在所有情况下都是隐藏的,属性是完全有效的,如果它在标签内,它不会被发送,因为它没有任何名称,对吧?
最重要的是,这些属性非常容易记忆,代码看起来不错且易于理解。您甚至可以在其中放置一个 ID 属性,这样您也可以使用 JavaScript 轻松访问它,并使用 .<form>
input.title; input.value
评论
使用 jquery,
存储:$('#element_id').data('extra_tag', 'extra_info');
要检索:$('#element_id').data('extra_tag');
在 html 中,我们可以在属性名称之前存储前缀为“data-”的自定义属性,例如
<p data-animal='dog'>This animal is a dog.</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>
解释
- 它使用 hidden 属性隐藏。不需要 CSS。
- 这是由 Javascript 处理的。我使用两个拆分语句,首先是换行符,然后是双逗号分隔符。这就把整个东西放到一个2D数组中。
- 我想尽量减少打字。我不想在每一行(json/jso 样式)上冗余地重新键入字段名,所以我只是将字段名放在第一行。这是程序员的视觉键,也被 Javascript 用来知道字段名。我取消了所有大括号、括号、等号、括号等。行尾是记录分隔符。
- 我使用双逗号作为分隔符。我想通常没有人会对任何事情使用双逗号,而且它们很容易输入。请注意,程序员必须为任何空单元格输入一个空格,以防止意外的双逗号。如果程序员愿意,他们可以很容易地使用不同的分隔符,只要他们更新 Javascript。如果您确定单元格中没有嵌入的逗号,则可以使用单逗号。
- 这是一个跨度,以确保它不会占用页面上的空间。
下面是 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 使用大量修剪来去除任何多余的空格。
评论