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

评论

相关问题:stackoverflow.com/questions/209428/…

#1 楼

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

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

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


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

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

评论


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

– Tamas Czinege
2010-1-24的2:58

其他人则声称没有理由等待支持,因为这导致的唯一问题是验证失败,并且不会破坏IE。见T.J.群众的回答在这里:stackoverflow.com/questions/1923278/…

–克里斯
2011-12-28 19:29



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

– Ohad Kravchick
2012年1月6日在22:29

注意性能! jsperf.com/jquery-data-vs-jqueryselection-data/19

– FilmJ
2012年4月6日14:35

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

–基甸·罗森塔尔(Gideon Rosenthal)
2014-09-11 22:07



#2 楼

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

要存储某些东西:

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


要检索数据:

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


这就是全部内容,但请查看jQuery文档以了解更多信息/ examples。

#3 楼

换一种方式,我个人不会使用它,但是它可以工作(确保您的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为横向思考。我同意我可能不想使用此方法,但这是一个可行的选择!

–nickf
09年1月11日,下午4:16

@nickf您可以使用JSON.parse代替jsfiddle.net/EAXmY摆脱评估

–西蒙
13-10-10在11:49

#4 楼

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

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

评论


为什么不使用数据属性呢?

– Flimm
17年5月26日在17:07

#5 楼

几乎所有可能的浏览器都可以使用的黑客方法是使用这样的开放类:<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,则将修改另一个副本。

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

评论


在课堂上存储valse很棒

–萨拉瓦南·拉贾曼(Saravanan Rajaraman)
16年1月21日在9:35



#6 楼

使用jquery,

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

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

#7 楼

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

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


#8 楼

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

– phylae
2011年11月12日在8:48

好的方法,在所有HTML版本中完全有效。我不鼓励编码,并假设所有用户都将使用完全兼容HTML5的浏览器。并显示:隐藏字段不需要。

– andreszs
14年8月14日在17:58

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

–阿拉曼
17年2月17日在18:21

#9 楼

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

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

评论


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

–ehdv
09年10月6日在14:03

#10 楼

作为jQuery用户,我将使用元数据插件。 HTML看起来很干净,可以验证,您可以嵌入任何可以使用JSON表示法描述的内容。

#11 楼

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

评论


该ID无法破坏链接上的nofollow属性

–卡特·科尔(Carter Cole)
2010-2-3在20:09

#12 楼

因此,应该有四个选择:


将数据放入id属性。
将数据放入任意属性
将数据放入类属性
将数据放入另一个标签

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

评论


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

–miguel-svq
2014年6月3日19:31



#13 楼

这是个好建议。感谢@Prestaul


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


非常正确,但是如果要将任意数据存储在纯HTML中怎么办?这是另一种替代方法...

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


将数据放入隐藏的输入元素的名称和值属性中。如果服务器正在生成HTML(即PHP脚本等),并且您的JavaScript代码稍后将使用此信息,则这可能很有用。诚然,这不是最干净的方法,但是它是替代方法。它与所有
浏览器兼容,并且是有效的XHTML。您不应该使用自定义属性,也不要使用带有'data-'前缀的属性,因为它可能不适用于所有浏览器。并且,此外,您的文档不会通过W3C验证。

评论


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

–BMiner
2011年10月11日在16:49

#14 楼

您可以使用您自己的随机元素的属性的数据前缀(<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-属性来保存一些工作。

–user4051844
15年7月8日在0:07

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

–叶提
15年7月8日在10:15

#15 楼

一种可能是:


创建一个新的div来保存所有扩展/任意数据
做一些确保该div不可见的操作(例如CSS加上cla​​ss属性为div)
在不可见的div中将扩展的/任意数据放入[X] HTML标记内(例如,作为表格单元格中的文本,或者您可能喜欢的其他任何内容)


#16 楼

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

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


这是有效的,并且可以使用jQuery选择器或a轻松检索。定制功能。

#17 楼

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

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

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

#18 楼

这就是我如何处理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="));
                   }
               }
           });
}


它是如何工作的,基本上是看所有具有该类的URL 'ajx',它将替换关键字并添加#号...因此,如果关闭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/

#19 楼

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


#20 楼

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

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

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

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

,然后为上述标签创建一个名为“繁殖”的属性,我们可以写:

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

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

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

#21 楼

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

–nickf
09年1月11日,下午4:35