自定义属性 - 是或不是?

TM.*_*TM. 254 html javascript xhtml custom-attribute

最近我一直在阅读越来越多关于在HTML标签中使用自定义属性的人,主要是为了嵌入一些额外的数据用于javascript代码.

我希望收集一些关于是否使用自定义属性是一个好习惯的反馈,以及一些替代方案.

现在看来似乎真的可以简化服务器端和客户端的代码,但它也不是W3C标准.

我们应该在我们的网络应用程序中使用自定义HTML属性吗?为什么或者为什么不?

对于那些认为自定义属性是好事的人:使用它们时要记住哪些事项?

对于那些认为自定义属性是坏事的人:你用什么方法来完成类似的事情?

更新: 我最感兴趣的是各种方法背后的推理,以及为什么一种方法比另一种更好的原因.我想我们都可以用4-5种不同的方式来完成同样的事情.(隐藏元素,内联脚本,额外类,从ids解析信息等).

更新2: 似乎HTML 5 data-属性功能在这里有很多支持(我倾向于同意,它看起来像一个可靠的选项).到目前为止,我还没有看到这个建议的反驳方式.使用这种方法是否有任何问题/陷阱?或者它只是对当前W3C规范的"无害"失效?

Chu*_*uck 254

HTML 5明确允许以自己开头的自定义属性data.因此,例如,<p data-date-changed="Jan 24 5:23 p.m.">Hello</p>有效.由于标准正式支持,我认为这是自定义属性的最佳选择.并且它不需要您使用hacks来重载其他属性,因此您的HTML可以保持语义.

资料来源:http: //www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes

  • 它与使用HTMLElement上的getAttribute()方法的所有浏览器完美配合.此外,随着HTML5数据集支持的增长,您可以轻松添加它. (12认同)
  • 我很确定它适用于旧浏览器; 将属性添加到DOM,您可以在其中访问它们. (8认同)
  • @Wahnfrieden:http://www.w3.org/TR/REC-html40/intro/sgmltut.html#idx-attribute-8这是经批准的,符合标准的方法.这里有很好的描述和演示:http://www.rodsdot.com/html/Specifying-Custom-HTML-Attributes-With-A-Custom-DOCTYPE.asp如前所述. (2认同)

Jam*_*mes 95

这是我最近使用的一种技术:

<div id="someelement">

    <!-- {
        someRandomData: {a:1,b:2},
        someString: "Foo"
    } -->

    <div>... other regular content...</div>
</div>
Run Code Online (Sandbox Code Playgroud)

comment-object绑定到父元素(即#someelement).

这是解析器:http://pastie.org/511358

要获取任何特定元素的数据,只需parseData使用对作为唯一参数传递的元素的引用进行调用:

var myElem = document.getElementById('someelement');

var data = parseData( myElem );

data.someRandomData.a; // <= Access the object staight away
Run Code Online (Sandbox Code Playgroud)

它可以比那更简洁:

<li id="foo">
    <!--{specialID:245}-->
    ... content ...
</li>
Run Code Online (Sandbox Code Playgroud)

访问它:

parseData( document.getElementById('foo') ).specialID; // <= 245
Run Code Online (Sandbox Code Playgroud)

使用它的唯一缺点是它不能与自闭元素(例如<img/>)一起使用,因为注释必须元素内被视为元素的数据.


编辑:

这项技术的显着优点:

  • 易于实施
  • 难道不是无效HTML/XHTML
  • 易于使用/理解(基本的JSON表示法)
  • 不像大多数替代品那样不引人注目且语义清晰

这是解析器代码(从上面的http://pastie.org/511358超链接复制,以防它在pastie.org上变得不可用):

var parseData = (function(){

    var getAllComments = function(context) {

            var ret = [],
                node = context.firstChild;

            if (!node) { return ret; }

            do {
                if (node.nodeType === 8) {
                    ret[ret.length] = node;
                }
                if (node.nodeType === 1) {
                    ret = ret.concat( getAllComments(node) );
                }
            } while( node = node.nextSibling );

            return ret;

        },
        cache = [0],
        expando = 'data' + +new Date(),
        data = function(node) {

            var cacheIndex = node[expando],
                nextCacheIndex = cache.length;

            if(!cacheIndex) {
                cacheIndex = node[expando] = nextCacheIndex;
                cache[cacheIndex] = {};
            }

            return cache[cacheIndex];

        };

    return function(context) {

        context = context || document.documentElement;

        if ( data(context) && data(context).commentJSON ) {
            return data(context).commentJSON;
        }

        var comments = getAllComments(context),
            len = comments.length,
            comment, cData;

        while (len--) {
            comment = comments[len];
            cData = comment.data.replace(/\n|\r\n/g, '');
            if ( /^\s*?\{.+\}\s*?$/.test(cData) ) {
                try {
                    data(comment.parentNode).commentJSON =
                        (new Function('return ' + cData + ';'))();
                } catch(e) {}
            }
        }

        return data(context).commentJSON || true;

    };

})();
Run Code Online (Sandbox Code Playgroud)

  • 应该能够更改/删除注释而不会破坏任何内容.这就是重点.因此,将标记或代码中的任何重要内容放入注释中是一个坏主意.未来的开发人员可以轻松地认为他们是评论并删除它们.我们已经有了这个问题的真正解决方案:以"data-"为前缀的自定义属性.绝不应该使用这种方法. (9认同)
  • 有人应该把它作为一个jquery插件 (7认同)
  • 让我强化@MGOwen的声明:不要使用注释来添加功能.特别是在HTML中.你不是在使用minifiers吗?在不破坏代码的情况下,您将无法删除评论.这也意味着您无法再添加真实的评论. (6认同)
  • 出于好奇,您使用什么方法来自动关闭标签?我通常需要在<input>元素上使用类似的东西(以帮助客户端验证规则).在那种情况下你有什么选择? (2认同)
  • 我可能会使用类似的技术,而不是绑定到"parentNode"的注释数据,它可以绑定到注释的"previousSibling"...然后你可以在<input />之后立即得到注释work:<input /> <! - {data:123} - > (2认同)

Bru*_*oLM 15

如果为页面指定了架构,则可以创建任何属性.

例如:

前页

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
...
<a addthis:title="" addthis:url="" ...>
Run Code Online (Sandbox Code Playgroud)

Facebook(甚至标签)

<html xmlns:og="http://opengraphprotocol.org/schema/" xmlns:fb="http://www.facebook.com/2008/fbml">
...
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>
Run Code Online (Sandbox Code Playgroud)


Jon*_*and 10

避免使用自定义属性的最简单方法是使用现有属性.

使用有意义的相关类名.
例如,执行以下操作:type='book'type='cd'表示书籍和CD.类更好地表示什么是IS.

例如 class='book'

我过去使用过自定义属性,但老实说,如果你以语义上有意义的方式使用现有属性,就没有必要为它们服务.

举一个更具体的例子,假设你有一个网站提供不同类型商店的链接.您可以使用以下内容:

<a href='wherever.html' id='bookstore12' class='book store'>Molly's books</a>
<a href='whereverelse.html' id='cdstore3' class='cd store'>James' Music</a>
Run Code Online (Sandbox Code Playgroud)

css样式可以使用如下类:

.store { }
.cd.store { }
.book.store { }
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们看到两者都是商店的链接(与网站上其他不相关的链接相对),一个是cd商店,另一个是书店.

  • 好的,但公平地说,"type"仅对某些标签有效,当它是一个有效的属性时,它还有一个有效值列表,所以你仍然不是真正符合w3c. (4认同)
  • @Jonathan双重类的东西效果很好,除非"值"不知道.例如,如果它是某种整数id,我们就不能很好地选择每种可能的情况.然后我们手动解析class属性,这绝对是可行的,但在代码中并不清楚,在某些情况下,可能非常慢(如果有很多候选元素要解析). (2认同)
  • 遗憾的是,同时为两个类编写css选择器(.ab注意缺少的空白)在IE中不起作用.它确实在Firefox和其他浏览器中工作.仍然,使用类是一种很好的方式来为您的标记嵌入额外的语义含义 (2认同)

ant*_*upe 6

嵌入的数据在DOM并使用元数据jQuery的.

所有好的插件都支持元数据插件(允许每个标签选项).

它还允许无限复杂的数据/数据结构以及键值对.

<li class="someclass {'some': 'random,'json':'data'} anotherclass">...</li>
Run Code Online (Sandbox Code Playgroud)

要么

<li class="someclass" data="{'some':'random', 'json': 'data'}">...</li>
Run Code Online (Sandbox Code Playgroud)

要么

<li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>
Run Code Online (Sandbox Code Playgroud)

然后得到如下数据:

var data = $('li.someclass').metadata();
if ( data.some && data.some == 'random' )
alert('It Worked!');
Run Code Online (Sandbox Code Playgroud)

  • 当有W3C批准的指定自定义属性的方法时,破坏class属性可能是您被拒绝的原因. (22认同)
  • 破坏class属性只是*使用插件的方法之一; 它不是唯一的*方式. (2认同)