Recently I have been reading more and more about people using custom attributes in their HTML tags, mainly for the purpose of embedding some extra bits of data for use in javascript code.
I was hoping to gather some feedback on whether or not using custom attributes is a good practice, and also what some alternatives are.
It seems like it can really simplify both server side and client side code, but it also isn't W3C compliant.
Should we be making use of custom HTML attributes in our web apps? Why or why not?
For those who think custom attributes are a good thing: what are some things to keep in mind when using them?
For those who think custom attributes are bad thing: what alternatives do you use to accomplish something similar?
Update: I'm mostly interested in the reasoning behind the various methods, as well as points as to why one method is better than another. I think we can all come up with 4-5 different ways to accomplish the same thing. (hidden elements, inline scripts, extra classes, parsing info from ids, etc).
Update 2: It seems that the HTML 5 data-
attribute feature has a lot of support here (and I tend to agree, it looks like a solid option). So far I haven't seen much in the way of rebuttals for this suggestion. Are there any issues/pitfalls to worry about using this approach? Or is it simply a 'harmless' invalidation of the current W3C specs?
Custom attributes. A custom attribute is a property that you can define to describe assets. Custom attributes extend the meaning of an asset beyond what you can define with the standard attributes. You can create a custom attribute and assign to it a value that is an integer, a range of integers, or a string.
Creating Custom Attributes (C#)The class name AuthorAttribute is the attribute's name, Author , plus the Attribute suffix. It is derived from System. Attribute , so it is a custom attribute class. The constructor's parameters are the custom attribute's positional parameters.
If you want to define your own custom attributes in HTML, you can implement them through data-* format. * can be replaced by any of your names to specify specific data to an element and target it in CSS, JavaScript, or jQuery.
NET custom attributes. Attributes are key-value pairs containing information that determines the properties of an event or transaction. You can create custom attributes using the AddCustomAttribute API.
HTML 5 explicitly allows custom attributes that begin with data
. So, for example, <p data-date-changed="Jan 24 5:23 p.m.">Hello</p>
is valid. Since it's officially supported by a standard, I think this is the best option for custom attributes. And it doesn't require you to overload other attributes with hacks, so your HTML can stay semantic.
Source: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes
Here's a technique I've been using recently:
<div id="someelement"> <!-- { someRandomData: {a:1,b:2}, someString: "Foo" } --> <div>... other regular content...</div> </div>
The comment-object ties to the parent element (i.e. #someelement).
Here's the parser: http://pastie.org/511358
To get the data for any particular element simply call parseData
with a reference to that element passed as the only argument:
var myElem = document.getElementById('someelement'); var data = parseData( myElem ); data.someRandomData.a; // <= Access the object staight away
It can be more succinct than that:
<li id="foo"> <!--{specialID:245}--> ... content ... </li>
Access it:
parseData( document.getElementById('foo') ).specialID; // <= 245
The only disadvantage of using this is that it cannot be used with self-closing elements (e.g. <img/>
), since the comments must be within the element to be considered as that element's data.
EDIT:
Notable benefits of this technique:
Here's the parser code (copied from the http://pastie.org/511358 hyperlink above, in case it ever becomes unavailable on 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; }; })();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With