截断字符串实现多行文本省略号+额外文字结尾

2024-02-21  本文已影响0人  Asuler

目标-小程序端:

  1. 最多两行,超出使用省略号
  2. 在省略号后面加入其他文案
  3. 尾部加入的文案可以点击
  4. 文字过少时单行不需要省略号和其他文案
  5. 效果图如下


    image.png

思路

单纯的css可以勉强实现这个效果,但是无法判断文字是否溢出,小程序端要获取dom信息很麻烦,得用异步的方法并且还和html的dom不一样

所以最后改成了用js手动判断,固定一行8个字,这样就能判断是否溢出了,然后使用字符串截取等方法分组渲染

先实现一个分组方法,给字符串每8个字一组分组

export function chunk(str, groupLength) {
  if (typeof str !== 'string') {
    return []
  }

  // 利用Array.from创建指定长度的数组,并映射为字符串片段
  return Array.from({ length: Math.ceil(str.length / groupLength) }, 
    (_, i) => str.slice(i * groupLength, (i + 1) * groupLength)
  );
}

然后截取分好的数组的前2组

import { View, Text } from '@tarojs/components';
import classNames from 'classnames';
import type React from 'react';
import { chunk } from '@/utils/common';
import styles from './index.module.scss';

interface EllipsisRowProps {
  content: string; //字符串内容
  rowLen: number; // 一行最多承载的字符数
  colLen: number; // 最多xx行
  className?: string; 
  moreText?: string; // 尾部的文字
  onMoreClick?: () => void; // 尾部的文字点击
}

const EllipsisRow: React.FC<EllipsisRowProps> = ({ content, rowLen = 8, colLen = 2, className, moreText = '全部', onMoreClick }) => {
  if (!content) {
    return null;
  }

  // 8个字符为一组, 截取前2组
  const originLines = chunk(content, rowLen);
  const lines = originLines.slice(0, colLen);

  // 判断是否溢出
  const isOverflow = originLines.length > lines.length;

  return (
    <View className={classNames(styles.wrapper, className)}>
      {lines.map((lineStr, index) => {
        // 最后一行并且是溢出的情况
        if (index === lines.length - 1 && isOverflow) {
          return (
            <View key={lineStr}>
              {lineStr.slice(0, 5)}...
              <Text className={styles.more} onClick={onMoreClick}>
                {moreText}
              </Text>
            </View>
          );
        }
        return <View key={lineStr}>{lineStr}</View>;
      })}
    </View>
  );
};

export default EllipsisRow;

上一篇 下一篇

猜你喜欢

热点阅读