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

nic*_*ckf 329 html javascript

我正在制作一个由javascript提供一些交互的页面.仅作为示例:发送AJAX请求以获取文章内容然后在div中显示该数据的链接.显然在这个例子中,我需要每个链接来存储额外的信息:文章的ID.我一直在处理它的方式是将这些信息放在href链接中:

<a class="article" href="#5">
Run Code Online (Sandbox Code Playgroud)

然后我使用jQuery来查找a.article元素并附加相应的事件处理程序.(不要太在意这里的可用性或语义,这只是一个例子)

无论如何,这种方法有效,但它有点味道,根本不可扩展(如果click函数有多个参数会发生什么?如果其中一些参数是可选的,会怎样?)

显而易见的答案是在元素上使用属性.我的意思是,这就是他们的目的,对吗?(的种类).

<a articleid="5" href="link/for/non-js-users.html">
Run Code Online (Sandbox Code Playgroud)

我最近的一个问题中,我问这个方法是否有效,结果是没有定义我自己的DTD(我没有),那么不,它是无效的或可靠的.一个常见的反应是将数据放入class属性中(虽然这可能是因为我选择不当的例子),但对我而言,这更令人闻趣.是的,它在技术上是有效的,但它不是一个很好的解决方案.

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

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

<a href="..." id="link0">
Run Code Online (Sandbox Code Playgroud)

但这可能是维持对接的真正痛苦,而且通常只是非常混乱.

那么,为了解决这个问题,你如何为HTML标签存储任意信息

Tam*_*ege 357

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

在HTML 5中,拥有带有数据前缀的自定义属性是完全有效的,例如

<div data-internalid="1337"></div>
Run Code Online (Sandbox Code Playgroud)

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

如果我是你,我会遵循基于脚本的方法.你可以在服务器端自动生成它,这样就不会让后面的人感到痛苦.

  • 如果您确实使用了data-xxx属性并且想要检索它们,那么您可以简单地使用"domElement.getAttribute('data-whatever')"而无需任何第三方框架. (42认同)
  • 提醒:为了检索数据,1337,通过jquery,一定要从变量名中删除'data'.例如,使用:`$(this).data('internalid');`而不是:`$(this).data('data-internalid');` (17认同)
  • 请记住性能!http://jsperf.com/jquery-data-vs-jqueryselection-data/19 (5认同)
  • @Tchalvak:是的,但是这一点在大多数浏览器上都可以使用. (4认同)
  • 其他人声称没有理由等待支持,因为这导致的唯一问题是验证失败,并且它不会破坏IE.请参阅TJ Crowler的答案:http://stackoverflow.com/questions/1923278/best-way-to-add-metadata-to-html-elements (2认同)

Pre*_*aul 134

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

存储东西:

$('#myElId').data('nameYourData', { foo: 'bar' });
Run Code Online (Sandbox Code Playgroud)

要检索数据:

var myData = $('#myElId').data('nameYourData');
Run Code Online (Sandbox Code Playgroud)

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


Luc*_*eis 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);
Run Code Online (Sandbox Code Playgroud)

  • @nickf你可以使用`JSON.parse`来摆脱`eval`而不是http://jsfiddle.net/EAXmY/ (9认同)
  • 这很好用,直到JS和CSS关闭,唉. (2认同)

Era*_*rin 12

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

另一种方法是在javascript中设置属性.jQuery有一个很好的实用方法,只是为了这个目的,或者你可以自己推出.

  • 为什么不使用`data -`属性呢? (2认同)

taw*_*taw 10

几乎所有可能的浏览器都可以使用的hack是使用这样的开放类: <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并且它们已被修改,您将需要手动处理它.


小智 10

使用jquery,

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

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


tva*_*son 6

我知道你现在正在使用jQuery,但如果你内联定义了onclick处理程序会怎样.然后你可以这样做:

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


phy*_*lae 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>
Run Code Online (Sandbox Code Playgroud)

使用jQuery,你会得到类似(未经测试)的文章ID:

$('.article input[name=articleid]').val();
Run Code Online (Sandbox Code Playgroud)

但如果可以选择,我会推荐HTML5.

  • 我实际上不认为隐藏输入字段需要`style ="display:none"`. (13认同)