在HTML5规范里,meter元素被定义为“已知范围内标量测量值的视觉化展示”,它和进度条progress最大的不同在于:meter描述的是一个静态或动态但已确定的度量,而不是任务完成度。实际项目中,我们常需要把后端算好的占用率、前端用户输入的分数,通过meter显示出来,同时还要在脚本里拿到这些度量做进一步判断。
一、meter元素的属性与度量含义
meter拥有一组描述度量区间的属性,理解它们是取数前的基础。其中value是当前实际度量值;min与max界定合法范围,默认分别是0和1;low与high把范围切出“低区”和“高区”;optimum则标记最理想的数值位置。浏览器会根据这些属性自动给meter上色,比如value落在low以下显示偏红,接近optimum显示偏绿。
很多初学者以为meter像input一样有value属性可直接提交,其实它只是展示型标签,不会被表单序列化。如果页面要把度量发给服务端,要么用隐藏域同步,要么用脚本读出来再拼到请求里。下面这段代码展示了一个磁盘使用率的meter:
<meter id="diskUsage" min="0" max="100" low="60" high="85" optimum="30"
value="72">72%</meter>
<p>当前磁盘使用率为 <span id="usageText">72</span>%</p>
上述标签中,value="72"就是我们要取的度量数据,low和high划定了警告区间。当value超过high,多数浏览器会把条变成黄色或红色,提示用户容量紧张。这种语义化展示比自己用div画进度条更省事,也利于屏幕阅读器识别。
二、用JavaScript读取meter的度量值
由于meter不是表单控件,获取它的度量数据只能通过DOM属性访问。最直白的办法是用getElementById拿到元素,然后读.value(返回浮点数)、.min、.max等。注意.value返回的是数字类型,不是字符串,所以比较时不用再parseFloat。
如果页面上有多个meter,比如展示CPU、内存、网络延迟,可以用querySelectorAll遍历,把每个id和value收集成对象,方便统一上报。下面示例演示单击按钮后取出度量并打印:
// 获取单个meter的度量
function getMeterValue(id) {
var m = document.getElementById(id);
if (!m) return null;
return {
value: m.value,
min: m.min,
max: m.max,
low: m.low,
high: m.high,
optimum: m.optimum
};
}
// 收集页面所有meter
function collectAllMeters() {
var result = {};
var list = document.querySelectorAll('meter');
list.forEach(function(el) {
result[el.id] = el.value;
});
return result;
}
document.getElementById('btn').addEventListener('click', function() {
console.log(getMeterValue('diskUsage'));
console.log(collectAllMeters());
});
这段代码里,getMeterValue把单个meter的全部边界和当前值打包返回,collectAllMeters则忽略边界只取value,实际项目可按需选用。需要提醒的是,若meter没写value属性,浏览器按min处理,脚本读到的是0或min值,不会抛错,这点容易引发隐蔽bug。
三、结合input实现可录入度量的meter
纯展示的meter无法让用户修改度量,常见需求是用户拖动range滑块,旁边meter实时反映分数或温度。此时用input type="range"负责录入,meter负责可视化,两者通过input事件同步。这种做法既保留meter的语义着色,又拥有交互能力。
同步逻辑很简单:监听range的input事件,把其值赋给meter.value,同时更新文字标签。下面的例子里,用户给员工打绩效分,分数0到100,低于60标红,高于90标绿:
<input type="range" id="scoreRange" min="0" max="100" value="75">
<meter id="scoreMeter" min="0" max="100" low="60" high="90" optimum="95"
value="75"></meter>
<span id="scoreLabel">75</span>
<script>
var range = document.getElementById('scoreRange');
var meter = document.getElementById('scoreMeter');
var label = document.getElementById('scoreLabel');
range.addEventListener('input', function() {
meter.value = range.value;
label.textContent = range.value;
});
</script>
这里meter的value被脚本动态改写,浏览器会立刻重绘颜色。如果要把这个分数提交,只需在表单提交前用前面写的getMeterValue读一下,或者直接从range.value拿,因为两者已绑定。该方案比用两个input互相拷贝更清晰,也避免用户直接改meter(它本来就改不了)。
四、取数时的常见误区与注意点
第一个误区是试图用formData获取meter值。前面说过meter不在表单提交序列里,new FormData(form)不会带它,开发者得手动append。第二个误区是认为meter和progress可以互换,把下载进度写成meter,导致读屏软件把它读成“测量”而非“进度”,体验错位。
另一个坑是optimum放错位置。如果optimum比high还大,浏览器仍按规则着色,但语义上“最优”却在警告区之外,脚本取optimum做判断时可能得出反直觉结论。建议写单测断言optimum在min和max之间,且和low、high关系符合业务预期。以下表格总结了关键属性取值规则:
| 属性 | 默认值 | 脚本读取字段 | 说明 |
|---|---|---|---|
| value | min | .value | 实际度量,数字型 |
| min | 0 | .min | 范围下界 |
| max | 1 | .max | 范围上界 |
| low | 等于min | .low | 低值阈值 |
| high | 等于max | .high | 高值阈值 |
| optimum | 中间值 | .optimum | 最佳度量点 |
掌握这些细节后,你就可以在仪表盘、问卷打分、资源监控等场景中稳妥地使用meter展示并取出度量数据,而不必自己造轮子写一堆div和css颜色判断。