React中如何获取渲染完成的better-react-mathjax组件宽度以适配图片?
解决MathJax渲染宽度匹配公式图片的问题
核心思路
由于better-react-mathjax无法直接通过ref获取渲染后的DOM元素宽度,我们可以通过监听LaTeX内容变化 + 异步捕获渲染完成后的元素实际宽度,再将这个宽度同步给公式图片,实现两者尺寸对齐。
具体实现步骤
- 新增状态变量存储渲染后公式的宽度
- 监听LaTeX内容的变化,等待MathJax完成异步渲染后获取元素宽度
- 将获取到的宽度赋值给图片的
width属性
修改后的代码示例
import { useState, useEffect } from 'react'; import { Grid, Box } from '@mui/material'; import MathJax from 'better-react-mathjax'; export default function FormulaComparer({ sourceImage, texSource }) { const [formulaWidth, setFormulaWidth] = useState(null); useEffect(() => { if (!texSource) return; // 等待MathJax完成异步渲染,延迟时间可根据实际渲染速度调整 const getWidthTimer = setTimeout(() => { const mathjaxElement = document.querySelector('.mathjaxElement'); if (mathjaxElement) { setFormulaWidth(mathjaxElement.offsetWidth); } }, 300); return () => clearTimeout(getWidthTimer); }, [texSource]); return ( <Grid container direction="column" spacing={2}> <Grid item> <fieldset> <legend>Original formula image</legend> <Box> <img width={formulaWidth || 'auto'} src={sourceImage} alt="Input image" style={{ objectFit: 'contain' }} /> </Box> </fieldset> </Grid> <Grid item> <fieldset> <legend>Dynamically rendered (corrected) formula</legend> <Box> <MathJax className="mathjaxElement" dynamic={true}> {'$$' + texSource + '$$'} </MathJax> </Box> </fieldset> </Grid> </Grid> ); }
优化方案(替代定时器)
如果觉得定时器不够可靠,可以用MutationObserver监听DOM变化,确保在MathJax渲染完成后再获取宽度:
useEffect(() => { if (!texSource) return; const observer = new MutationObserver(() => { const mathjaxElement = document.querySelector('.mathjaxElement'); if (mathjaxElement) { setFormulaWidth(mathjaxElement.offsetWidth); observer.disconnect(); } }); const target = document.querySelector('.mathjaxElement'); if (target) { observer.observe(target, { childList: true, subtree: true }); } return () => observer.disconnect(); }, [texSource]);
注意点
- 图片添加
objectFit: 'contain'可以保证按比例缩放,避免强制宽度导致的变形 - 若使用自定义样式类,确保
mathjaxElement类能准确选中MathJax渲染后的容器元素
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

