In HTML5, the data-*
attributes were codified, and this is a really nice thing for building applications. They are an app-defined namespace to attach any sorts of custom data to your HTML attributes. For example, a div responsible for displaying a User
object might have an attribute like <div data-user-id="5123">…</div>
, which allows us to better bind our DOM to our application model. They can even be used in stylesheet selectors, so I could make a styling rule for div[data-user-id]
.
I’m not the only one who thinks they’re a nice feature. Eric W has a co-worker who’s come up with a very… unique way of using them. First, he has the following Django template:
{% for cat in categories %}
<a href="#" {% if shopType == cat.name|slugify %}class="navOn" {% endif %}data-type="{{ cat.name|slugify }}" data-id="{{ cat.id }}">{{ cat.name }}</a>
{% endfor %}
Which generates links like: <a href="#" data-type="housewares" data-id="54">Housewares</a>
Obviously, since the href
points nowhere, there must be a JavaScript event handler. I wonder what it does…
$('.shop-nav a').unbind('click').click(function(e){
e.stopPropagation();
var page = $(this).data('type');
window.location.href = window.location.origin+'/shop/'+ page;
return false;
})
This is one of my favorite classes of bad code- the one where a developer uses a new feature to completely reinvent an old feature, badly. This JavaScript uses the data-type
attribute to hold what should actually be in the href
. Instead of having real navigation, we hijack the click event to force navigation. The entire JavaScript could be replaced in favor of a link like this: <a href="/shop/housewares">Housewares</a>
.
Maybe they need data-type
because there’s a CSS rule that styles it?