Houdini-CSS Typed OM:如何更简洁地通过JS获取已注册自定义属性值?
应用场景
你已经通过CSS.registerProperty将自定义属性--animation-duration注册为时间类型:
CSS.registerProperty({ name: '--animation-duration', syntax: '<time>', inherits: false, initialValue: '1s' });
在CSS中为类设置该属性值:
.my-el { --animation-duration: 1.5s; }
目前你通过以下代码获取该元素上此属性的毫秒值:
const duration = CSSNumericValue.parse(getComputedStyle(el).getPropertyValue('--animation-duration')).to('ms').value; // 返回1500
问题
在常规JavaScript环境中,有没有更简洁、更优的方法来获取这个属性值?
我的解答
首先得说,目前在常规JS里,最可靠且相对简洁的方案还是基于getComputedStyle+CSSNumericValue.parse的组合,不过我们可以把它封装成复用性更高的工具函数,让调用更简洁:
// 封装成可复用的工具函数 function getRegisteredTimePropInMs(element, propName) { const computedValue = getComputedStyle(element).getPropertyValue(propName).trim(); return CSSNumericValue.parse(computedValue).to('ms').value; } // 调用示例 const duration = getRegisteredTimePropInMs(el, '--animation-duration'); // 1500
为什么attributeStyleMap不起作用?
你提到的el.attributeStyleMap.get(...)方案失效,是因为attributeStyleMap仅针对元素的内联样式(也就是写在style属性里的样式)生效,而且它不会自动解析计算后的样式值。如果你的--animation-duration是通过CSS类、外部样式表设置的,attributeStyleMap根本拿不到这个值;哪怕是内联设置,它返回的CSSStyleValue也需要额外处理,并不比现有方案更简洁。
Worklet里的properties.get(...)之所以简洁,是因为Worklet环境专门提供了对已注册自定义属性的直接解析支持,但这个能力目前并没有延伸到常规JS环境中。
有没有更短的原生写法?
遗憾的是,目前原生JS并没有提供比封装后的工具函数更简洁的方式。除非未来浏览器扩展了getComputedStyle的能力,直接支持返回已解析的CSSNumericValue类型的自定义属性值,否则我们只能依赖现有的组合方案。
内容的提问来源于stack exchange,提问作者Ibe Vanmeenen

