如何从CSS Module中读取CSS规则的transition-duration属性值?
默认CSS Module导出的styles对象仅包含类名和编译后哈希类名的映射,不会携带CSS内部的属性值,要实现时长复用可以用以下两种方案:
方案1:运行时读取DOM实际样式(无需修改构建配置,最准确)
直接通过DOM API读取元素最终计算后的过渡时长,完全以CSS实际生效值为准,无需额外依赖,修改CSS时长不需要同步改动JS代码。
// MyComponent.js import { useState, useRef, useEffect } from "react" import styles from "./MyComponent.module.css" const MyComponent = () => { const [isAnimating, setIsAnimating] = useState(false) const animRef = useRef(null) const [transitionDuration, setTransitionDuration] = useState(0) // 组件挂载后读取过渡时长 useEffect(() => { if (!animRef.current) return const computedStyle = getComputedStyle(animRef.current) const durationStr = computedStyle.transitionDuration let duration = 0 // 适配s和ms两种单位 if (durationStr.endsWith('ms')) { duration = parseFloat(durationStr) } else if (durationStr.endsWith('s')) { duration = parseFloat(durationStr) * 1000 } // 存在多个过渡属性时可拆分字符串取最大值,此处为简化实现 setTransitionDuration(duration) }, []) const classes = `${styles.animatable} ${isAnimating? styles.animating : ''}` const clickHandler = () => { setIsAnimating(true) setTimeout(() => setIsAnimating(false), transitionDuration) } return <div ref={animRef} className={classes} onClick={clickHandler}>Click me.</div> } export default MyComponent
方案2:构建时通过CSS Module导出变量复用(静态编译,无运行时开销)
使用CSS Module的@value功能(大部分React脚手架默认已支持对应postcss插件),把时长定义为公共变量,同时导出到JS侧使用,全程静态编译没有额外运行时性能损耗。
首先修改CSS文件:
/* MyComponent.module.css */ @value transition-duration: 500ms; .animatable { background-color: red; transition-property: background-color; transition-duration: transition-duration; } .animating { background-color: grey; }
再修改JS文件直接导入定义好的时长变量:
// MyComponent.js import { useState } from "react" import styles, { transitionDuration } from "./MyComponent.module.css" const MyComponent = () => { const [isAnimating, setIsAnimating] = useState(false) // 把导入的时长字符串转成毫秒数 const duration = transitionDuration.endsWith('ms') ? parseFloat(transitionDuration) : parseFloat(transitionDuration) * 1000 const classes = `${styles.animatable} ${isAnimating? styles.animating : ''}` const clickHandler = () => { setIsAnimating(true) setTimeout(() => setIsAnimating(false), duration) } return <div className={classes} onClick={clickHandler}>Click me.</div> } export default MyComponent
内容的提问来源于stack exchange,提问作者theberzi
相关产品推荐
相关产品推荐

