首页 > 解决方案 > 在两行文本后添加省略号和工具提示 - React

问题描述

是否可以创建一个 React 组件,它可以在两行之后添加省略号并仅在文本被换行时才显示工具提示?

尝试使用“noWrap”属性和其他 CSS 自定义 Material UI 的 Typography 组件,但失败了。

请协助,我想实现这样的屏幕: 在此处输入图像描述

标签: cssreactjsmaterial-uijss

解决方案


这个问题主要有两个方面:

  • 根据垂直溢出显示文本溢出的省略号,以便允许多行但不是无限的
  • 在这种情况下检测垂直溢出并包含工具提示功能

我不相信 FrankerZ 的解决方案会显示省略号。据我所知,text-overflow: ellipsis仅适用于需要将文本限制为单行的水平溢出。

我在这里找到了一个在垂直溢出上进行省略的解决方案,但是一旦你开始将它包装在 Material UI 组件(例如 ListItem)中,它可能需要进行重大调整,这会带来额外的 CSS,并且它可能会变得足够复杂以至于不值得. 该解决方案的效果是在每行文本的末尾为省略号保留空间,这似乎并不理想。这个问题似乎还有其他一些解决方案,但我自己没有使用过任何一个(包括今天以外的这个)。

第二部分(检测溢出)似乎更直接,由divRef.current.scrollHeight > divRef.current.offsetHeight. 我通过找到许多关于根据宽度进行类似条件的参考来得出这个解决方案。在处理这个答案时,我没有在今天之外亲自使用过这种技术,所以有更深入的 CSS 专业知识的人可能会说“你永远不应该这样做,因为......”,但它似乎有效(我没有做过任何重要的浏览器测试——仅在 Chrome 上尝试过)。

为了语法方便,我在示例中使用了钩子,因此如果您不使用 alpha,则需要将状态、引用和效果工作转换为相应的类对应项。这目前也没有处理调整窗口大小,这需要重新评估工具提示是否应该生效。有了这些警告,希望这将为您提供一些可行的解决方案。

这是代码:

import React, { useRef, useState, useEffect } from "react";
import ReactDOM from "react-dom";
import Tooltip from "@material-ui/core/Tooltip";
import { withStyles } from "@material-ui/core/styles";
/* 
CSS from http://hackingui.com/front-end/a-pure-css-solution-for-multiline-text-truncation/ 
Additional syntax help from https://stackoverflow.com/questions/40965977/cant-target-before-pseudo-selector-in-jss
*/
const styles = theme => ({
  listItem: {
    maxWidth: "20rem",
    overflow: "hidden",
    position: "relative",
    lineHeight: "1.2em",
    maxHeight: "2.4em",
    textAlign: "justify",
    marginRight: "-1em",
    paddingRight: "1em",
    borderBottom: "1px solid",
    marginBottom: "0.5em",
    "&&:before": {
      content: '"..."',
      position: "absolute",
      right: 0,
      bottom: 0
    },
    "&&:after": {
      content: '""',
      position: "absolute",
      right: 0,
      width: "1em",
      height: "1em",
      marginTop: "0.2em",
      background: "white"
    }
  }
});
const data = [
  "Some short text",
  "Some text that is a little bit longer",
  "Some text that will need to wrap but still fits on two lines",
  "Some text that will overflow because it is more than just two lines worth when the maxWidth is set at 20rem.",
  "A massive range of hammer drill machines and rotary hammers for SDS-plus accessory tools, designed for higher performance drilling and longer life - for easy drilling in concrete and other materials."
];
const TooltipDiv = props => {
  const divRef = useRef(null);
  const [allowTooltip, setAllowTooltip] = useState(false);
  useEffect(() => {
    if (
      !allowTooltip &&
      divRef.current.scrollHeight > divRef.current.offsetHeight
    ) {
      setAllowTooltip(true);
    }
  }, []);
  if (allowTooltip) {
    return (
      <Tooltip title={props.text}>
        <div ref={divRef} className={props.className}>
          {props.text}
        </div>
      </Tooltip>
    );
  }
  return (
    <div ref={divRef} className={props.className}>
      {props.text}
    </div>
  );
};
function App(props) {
  return (
    <>
      {data.map(text => {
        return (
          <>
            <TooltipDiv text={text} className={props.classes.listItem} />
          </>
        );
      })}
    </>
  );
}
const StyledApp = withStyles(styles)(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<StyledApp />, rootElement);

你可以在这里看到它的实际效果:

编辑 4xn3386z6x


推荐阅读