首页 文章

自定义属性 - 是或不是?

提问于
浏览
247

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

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

它似乎可以真正简化服务器端和客户端代码,但它也不符合W3C .

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

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

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

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

Update 2: 似乎HTML 5 data- 属性功能在这里有很多支持(我倾向于同意,它看起来像一个可靠的选项) . 到目前为止,我还没有“无害”当前W3C规范的失效?

14 回答

  • 4

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

    例如:

    Addthis

    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
    ...
    <a addthis:title="" addthis:url="" ...>
    

    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"/>
    
  • 1

    HTML 5明确允许以 data 开头的自定义属性 . 因此,例如, <p data-date-changed="Jan 24 5:23 p.m.">Hello</p> 是有效的 . 由于's officially supported by a standard, I think this is the best option for custom attributes. And it doesn' t要求您使用hacks来重载其他属性,因此您的HTML可以保持语义 .

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

  • 1

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

    <div id="someelement">
    
        <!-- {
            someRandomData: {a:1,b:2},
            someString: "Foo"
        } -->
    
        <div>... other regular content...</div>
    </div>
    

    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
    

    它可以比那更简洁:

    <li id="foo">
        <!--{specialID:245}-->
        ... content ...
    </li>
    

    访问它:

    parseData( document.getElementById('foo') ).specialID; // <= 245
    

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


    EDIT

    这项技术的显着优点:

    • 易于实施

    • 不会使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;
    
        };
    
    })();
    
  • 246

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

    使用有意义的相关类名 .
    例如,执行以下操作: 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>
    

    css样式可以使用如下类:

    .store { }
    .cd.store { }
    .book.store { }
    

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

  • 1

    将数据嵌入dom并使用metadata for jQuery .

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

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

    <li class="someclass {'some': 'random,'json':'data'} anotherclass">...</li>
    

    要么

    <li class="someclass" data="{'some':'random', 'json': 'data'}">...</li>
    

    要么

    <li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>
    

    然后得到如下数据:

    var data = $('li.someclass').metadata();
    if ( data.some && data.some == 'random' )
    alert('It Worked!');
    
  • 95

    我发现在不破坏任何内容或扩展命名空间的情况下使用现有的XHTML功能没有问题 . 我们来看一个小例子:

    <div id="some_content">
     <p>Hi!</p>
    </div>
    

    如何在没有其他属性的情况下向some_content添加其他信息?如何添加如下标签?

    <div id="some_content">
     <div id="some_content_extended" class="hidden"><p>Some alternative content.</p></div>
     <p>Hi!</p>
    </div>
    

    它通过您选择的明确定义的id / extension“_extended”以及它在层次结构中的位置来保持关系 . 我经常将这种方法与jQuery一起使用,而不使用像Ajax这样的技术 .

  • 6

    我没有使用自定义属性,因为我正在输出XHTML,因为我希望数据是机器可读的第三方软件(但是,如果我愿意的话,我可以扩展XHTML架构) .

    作为自定义属性的替代,我发现id和类属性(例如在其他答案中提到的)足够 .

    另外,考虑一下:

    • 如果额外数据是人类可读的以及机器可读的,那么它需要使用(可见的)HTML标签和文本而不是自定义属性进行编码 .

    • 如果它不需要是人类可读的,那么也许它可以使用不可见的HTML标签和文本进行编码 .

    有些人例外:它们允许自定义属性,在运行时通过Javascript在客户端添加到DOM . 他们认为这没关系:因为自定义属性仅在运行时添加到DOM,所以HTML不包含自定义属性 .

  • 0

    不仅如此 . 尝试这样的事情:

    <div id="foo"/>
    
    <script type="text/javascript">
      document.getElementById('foo').myProperty = 'W00 H00! I can add JS properties to DOM nodes without using custom attributes!';
    </script>
    
  • 15

    我们创建了一个基于Web的编辑器,可以理解HTML的一个子集 - 一个非常严格的子集(几乎普遍由邮件客户端理解) . 我们需要在数据库中表达类似 <td width="@INSWIDTH_42@"> 的内容,但我们可以't have that in the DOM, otherwise the browser where the editor runs, freaks out (or is more likely to freak out than it is likely to freak out over custom attributes). We wanted drag-and-drop, so putting it purely in the DOM was out, as was jquery' s .data() (额外的数据没有被正确复制) . 在 .html() 中,我们可能还需要额外的数据 . 最后我们决定在编辑过程中使用 <td width="1234" rs-width="@INSWIDTH_42@"> ,然后当我们全部POST时,我们删除 width 并进行正则表达式搜索并销毁 s/rs-width=/width=/g .

    首先,写这个问题的人是关于这个问题的验证纳粹,并尝试了一切以避免我们的自定义属性,但最终默认当没有别的东西似乎适用于我们所有的要求 . 当他意识到自定义属性永远不会出现在电子邮件中时,它有所帮助我们确实考虑在 class 中编码我们的额外数据,但决定这将是两个邪恶中的更大一个 .

    就个人而言,我更喜欢让事情干净并通过验证员等,但作为一名公司员工,我必须记住,我的主要责任是推进公司的事业(尽可能快地赚钱),而不是我的自负 . 技术纯度 . 工具应该对我们有用;不是我们的 .

  • 2

    我知道人们反对它,但我想出了一个超短的解决方案 . 如果你想使用像“我的”这样的自定义属性,例如:

    <a href="test.html" mine-one="great" mine-two="awesome">Test</a>
    

    然后你可以像jquery.data()一样运行这段代码来获取一个对象 .

    var custom_props = {} ;
    $.each($(".selector")[0].attributes, function(i,x) {
        if (this.specified && x.name.indexOf("mine-") !== -1) 
            self.new_settings[x.name.replace("modal-","")] = x.value;
    });
    
  • 0

    规范:创建一个ASP.NET TextBox控件,根据属性"DecimalSeparator"和"ThousandsSeparator",使用JavaScript动态地将其文本格式化为数字 .

    将这些属性从控件传输到JavaScript的一种方法是让控件呈现自定义属性:

    <input type="text" id="" decimalseparator="." thousandsseparator="," />
    

    JavaScript可以轻松访问自定义属性 . 虽然使用具有自定义属性的元素的页面不会validate,但该页面的呈现不会受到影响 .

    当我想将字符串和整数等简单类型与HTML元素相关联以便与JavaScript一起使用时,我会使用这种方法 . 如果我想让HTML元素更容易识别,我将使用class和id属性 .

  • 0

    我一直使用自定义字段,例如<a i =“”....然后使用jquery引用i . 无效的HTML,是的 . 它运作良好,是的 .

  • -2

    对于复杂的Web应用程序,我会在整个地方删除自定义属性 .

    对于更多面向公众的页面,我使用“rel”属性并将所有数据转储到JSON中,然后使用MooTools或jQuery对其进行解码:

    <a rel="{color:red, awesome:true, food: tacos}">blah</a>
    

    我最近试图坚持HTML 5数据属性只是为了“准备”,但它还没有自然而然 .

  • 10

    我认为不应该使用自定义属性,因为它们不会验证 . 除此之外,您可以为单个元素定义许多类,例如:

    <div class='class1 class2 class3'>
        Lorem ipsum
    </div>
    

相关问题