XHTML 作为 HTML5 数据属性的替代方案





4.00/5 (4投票s)
使用 CSS 选择器作为轻量级的键值对;在运行时使用 bindCssData 方法自动绑定到元素。
引言
我倾向于编写自己的跨浏览器 UI 组件,并且始终努力减少页面渲染的元素数量,同时确保标记验证有效。在需要键值对但不想插入隐藏字段的情况下,我使用自定义 CSS 选择器,例如
<div id="mydiv" class="data-usedialogs-true">
prefix-key-value
然后,我有一个脚本在页面加载时执行,遍历所有(或选定的)元素,提取键值对并将它们绑定到 DOM 中的实际元素。
这允许我使用 JavaScript 读取/测试值,而无需手动解析。
var mydiv = document.getElementById("mydiv");
if (mydiv.prefix.property=="true")
{
// do something...
}
这种方法是我的符合 W3C 标准的(HTML5 之前的)HTML5 数据属性的替代方案,你可以将自定义数据属性添加到元素,例如
<div id="mydiv" data-usedialogs="true">
这种方法的好处是可以更改属性,所以你可以拥有
<div id="mydiv" class="settings-autohide-true">
结果是:
var mydiv = document.getElementById("mydiv");
if (mydiv.settings.autohide=="true")
{
// do something...
}
脚本是如何工作的?
当脚本执行时,它会在 DOM 中查找所有类名与正则表达式 prefix-[A-Za-z0-9]{1,}- [A-Za-z0-9]{1,} 匹配的元素。一旦找到一个元素,它就会在该元素上创建一个自定义属性,并分配一个包含在匹配选择器中找到的键和值的数组。
这意味着你可以在同一个元素内拥有多个键值对
<div id="mydiv" class="data-usedialogs-true data-autohide-true">
允许你在 JavaScript 中将值读回,如下所示
var mydiv = document.getElementById("mydiv");
if (mydiv.data.usedialogs=="true")
{
// do something...
}
和
var mydiv = document.getElementById("mydiv");
if (mydiv.data.autohide=="true")
{
// do something...
}
该脚本
//
// turns custom class names into key/value expando properties
//
// css class data-title-hello can be retrieved using element.data.title
//
function bindCssData(t /*tagName*/, p /*prefix*/)
{
p = p || "data";
t = t || "*";
var els = document.getElementsByTagName(t);
var reg = new RegExp("^(" + p + ")-([A-Z0-9]{1,})-([A-Z0-9]{1,})$", "i");
for (var i=0, l=els.length; i<l; i++)
{
var cssNames = (els[i].className != "") ?
new String(els[i].className).split(' ') : [];
if (cssNames.length<=0) continue;
for (var ii=0, ll=cssNames.length; ii<ll; ii++)
{
var m = reg.exec(cssNames[ii]);
if (m && m.length >= 2) {
els[i][p] = els[i][p] || new Array();
els[i][p][m[2]] = m[3];
}
}
}
}
要使用该脚本,请在 window.onload
函数中调用 bindCssData()
。 如果你没有向该函数传递任何参数,它将解析所有元素,查找前缀为 data 的元素。 为了提高速度,请考虑仅使用你想要影响的元素类型(tagName)调用该函数。
bindCssData("span");
或
bindCssData("span", "settings");
预期的反击 -> 自动回复
当然,会有许多设计师/开发人员不同意使用 CSS 选择器将数据传递给客户端脚本的概念。 但是,为了我的辩护,并考虑到渐进增强,这是我在不向页面插入不必要的臃肿的情况下想到的最干净的解决方案。 此外,定义自己的前缀的能力可以减少与实际页面样式冲突的可能性。
例如,你可以使用不自然的 CSS 选择器,例如 __cssdata-key-value。
反馈
我总是很忙,没有太多时间来撰写这些文章,所以可能有些地方缺乏解释。 如果你觉得我需要扩展/更正任何内容,请留下评论,我会尽快更新它。