如何为某些HTML标签存储任意数据


338

我正在制作一个页面,该页面具有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标签的任意信息


Answers:


361

您正在使用哪个版本的HTML?

在HTML 5中,使用以data-开头的自定义属性是完全有效的,例如

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

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

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


5
@Tchalvak:是的,但是此位将在大多数浏览器上都有效,尽管如此。
Tamas Czinege

2
其他人则声称没有理由等待支持,因为这导致的唯一问题是验证失败,并且不会破坏IE。请在此处查看TJ Crowler的答案:stackoverflow.com/questions/1923278/…–
克里斯(Chris)

42
如果您确实使用data-xxx属性并且要检索它们,则可以简单地使用“ domElement.getAttribute('data-whatever')”,而无需任何第三方框架。
Ohad Kravchick 2012年


19
提醒:为了通过jquery检索数据,请确认1337,确保从变量名中删除“数据”。例如,使用: $(this).data('internalid'); 而不是:$(this).data('data-internalid');
Gideon Rosenthal

134

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

存储东西:

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

要检索数据:

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

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


20

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

1
+1为横向思考。我同意我可能不想使用这种方法,但这是一个可行的选择!
尼克

9
@nickf你可以摆脱eval使用JSON.parse代替jsfiddle.net/EAXmY
西蒙

12

任意属性无效,但在现代浏览器中绝对可靠。如果您通过javascript设置属性,那么您也不必担心验证。

另一种方法是在javascript中设置属性。jQuery 为此提供了一个很好的实用程序方法,或者您可以自己滚动。


3
为什么不使用data-属性呢?
Flimm

10

几乎所有可能的浏览器都可以使用的黑客方法是使用这样的开放类: <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(在这里并不重要),也许某些浏览器会完全混乱,您需要检查一下。

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

除非您尝试复制标签,否则使用idsJS哈希通常可以工作。如果有tag <a href="..." id="link0">,请通过标准JS方法将其复制,然后尝试修改data仅附接到一个副本的附件,否则将修改另一个副本。

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


在课堂上存储价格太棒了
Saravanan Rajaraman

10

使用jQuery,

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

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


6

我知道您当前正在使用jQuery,但是如果您内联定义了onclick处理程序,该怎么办。然后,您可以执行以下操作:

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

6

您可以使用隐藏的输入标签。我在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。


13
我实际上认为style="display: none"隐藏的输入字段不需要。
phylae 2011年

1
好的方法,在所有HTML版本中完全有效。我不鼓励编码,但前提是您所有的用户都将拥有完全兼容HTML5的浏览器。并显示:隐藏字段不需要。
andreszs

非常好。这是我发现的XHTML的最佳解决方案,其中数据属性不是有效的选择。IMO不会以意想不到的方式滥用标签/属性,几乎没有任何“气味”。正如其他人所说:display:并不需要。
Arahman '17

4

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

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


2
问题在于它也不是真正可扩展的
ehdv


3

因此,应该有四个选择:

  1. 将数据放在id属性中。
  2. 将数据放入任意属性
  3. 将数据放在类属性中
  4. 将您的数据放在另一个标签中

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


@ h4ck3rm1k3 ...不在id属性中,因为它在文档中必须是唯一的,如果有必要,应在边栏或其他内容中将其重复...这是一个老问题,但仍然有效
miguel-svq

2

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


无法做到该ID破坏链接上的nofollow属性
Carter Cole 2010年

2

这是个好建议。感谢@Prestaul

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

的确如此,但是如果您想在纯HTML中存储任意数据怎么办?这是另一种选择...

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

将数据放在隐藏输入元素的名称和值属性中。如果服务器正在生成HTML(即PHP脚本等),并且您的JavaScript代码稍后将使用此信息,则这可能很有用。

诚然,这不是最干净的方法,但是它是替代方法。它与所有浏览器兼容,并且是有效的XHTML。您不应该使用自定义属性,也不要使用带有'data-'前缀的属性,因为它可能不适用于所有浏览器。并且,此外,您的文档不会通过W3C验证。


不确定,但是如果您使用具有“严格”文档类型的自定义属性,某些浏览器可能会抱怨。无论哪种方式,它都不是有效的XHTML。
BMiner 2011年

2

您可以使用您自己的随机元素(<span data-randomname="Data goes here..."></span>)的属性的数据前缀,但这仅在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


我确信您没有足够地使用html表和选择。您将更经常使用data-属性来保存一些工作。

1
实际上,我确实经常使用'data-'属性。但这取决于您的要求。例如,使用<input />可以有任何键,而对于'data-',则最好限制为小写字符串,且不包含任何非字母数字字符。
Yeti

1

一种可能是:

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

1

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

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

这是有效的,可以使用jQuery选择器或自定义函数轻松检索。


0

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

当时对于FireFox来说效果不佳。我不知道FireFox是否已更改此设置,但请注意,读者的浏览器可能不支持将自己的属性添加到HTML元素。

如果您可以控制读者使用的浏览器(例如,公司的内部Web小程序),则请务必尝试一下。会疼什么,对吗?


0

这就是我为您提供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”类的网址,并替换关键字并添加#号...因此,如果关闭js,则这些网址将照常运行... all“ apps”(网站的每个部分)都有自己的关键字...因此,我需要做的就是添加到上面的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/


0

我发现元数据插件是解决带有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"/>

0

在html中,我们可以在属性名称之前存储带有前缀“ data-”的自定义属性,例如

<p data-animal='dog'>This animal is a dog.</p>。检查文件

我们可以使用jQuery这样的属性来动态设置和获取属性,例如:如果我们有ap标签,例如

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

然后,为上面的标签创建一个名为“ breed”的属性,我们可以编写:

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

要随时检索数据,我们可以编写:

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


0

只要您的实际工作是在服务器端完成的,为什么仍然需要在输出的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>

您应该如何将数据传递给javascript?
尼克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.