RN 如何实现H5 sub 下标标签

今天发现客户端一个乱码问题,定位发现,是一个化学表达式,在RN 中没支持<sub>标签导致的。查了一下,如果用 text 实现,其实挺麻烦,性能也比较差。

天津大学王彬教授团队设计并合成了新型Meerwein型离子对三甲基氧鎓四五氟苯基硼酸盐(Me<sub>3</sub>O\]\&#91;B(C<sub>6</sub>F<sub>5</sub>)<sub>4</sub>\])

方法 1:使用 Text 和样式调整

React Native 的 Text 组件支持嵌套,可以通过调整 fontSizelineHeight 模拟上标或下标。

import React from 'react';
import { Text, StyleSheet } from 'react-native';

export default function App() {
  return (
    <Text style={styles.text}>
      Me
      <Text style={styles.subscript}>3</Text>O
    </Text>
  );
}

const styles = StyleSheet.create({
  text: {
    fontSize: 16, // 主字体大小
  },
  subscript: {
    fontSize: 10, // 下标字体大小
    lineHeight: 16, // 对齐主文字
    textAlignVertical: 'bottom',
  },
});

方法 2:使用 Unicode 字符

一些常见的上下标可以直接用 Unicode 表示。例如:

  • 上标数字:¹²³
  • 下标数字:₁₂₃
import React from 'react';
import { Text } from 'react-native';

export default function App() {
  return (
    <Text>Me₃O</Text>
  );
}

方法 3:通过 SVG 渲染

如果需要更灵活的排版,可以使用 react-native-svg 来绘制带有上下标的文字。

npm install react-native-svg
import React from 'react';
import { View } from 'react-native';
import Svg, { Text as SvgText, TSpan } from 'react-native-svg';

export default function App() {
  return (
    <View>
      <Svg height="50" width="100">
        <SvgText
          x="0"
          y="20"
          fontSize="16"
          fill="black"
        >
          Me
          <TSpan
            fontSize="10"
            baselineShift="sub"
          >
            3
          </TSpan>
          O
        </SvgText>
      </Svg>
    </View>
  );
}

最终选择了使用Unicode 来进行正则替换,简单直接,兼容性好,性能好。

function replaceHtmlSubSup(input) {
  // 定义上标和下标的映射
  const superscriptMap = { 0: '⁰', 1: '¹', 2: '²', 3: '³', 4: '⁴', 5: '⁵', 6: '⁶', 7: '⁷', 8: '⁸', 9: '⁹' };
  const subscriptMap = { 0: '₀', 1: '₁', 2: '₂', 3: '₃', 4: '₄', 5: '₅', 6: '₆', 7: '₇', 8: '₈', 9: '₉' };

  // 替换下标 <sub>...</sub>
  input = input.replace(/<sub>(\d+)<\/sub>/g, (_, digits) => {
    return digits.split('').map(digit => subscriptMap[digit]).join('');
  });

  // 替换上标 <sup>...</sup>
  input = input.replace(/<sup>(\d+)<\/sup>/g, (_, digits) => {
    return digits.split('').map(digit => superscriptMap[digit]).join('');
  });

  return input;
}

// 示例测试
const htmlText = "H<sub>2</sub>O and E = mc<sup>2</sup>";
const result = replaceHtmlSubSup(htmlText);

console.log(result);
// 输出: H₂O and E = mc²

Leave a Comment

邮箱地址不会被公开。 必填项已用*标注