如果 CSS 省略号在 React 组件中处于活动状态,如何有条件地显示标题工具提示

mka*_*man 7 javascript reactjs

问题

我正在寻找一种干净的方法来在应用了 CSS 省略号的项目上显示标题工具提示。(在 React 组件内)

我尝试过的:

我设置了一个 ref,但直到 componentDidUpdate 之前它才存在,因此在 componentDidUpdate 中我强制更新。(这需要更多的返工来处理 prop 更改等,我可能会使用 setState 来代替。)这种方法可行,但有很多我认为不可接受的警告。

  1. setState/forceUpdate - 也许这是一个必要的邪恶
  2. 如果浏览器尺寸改变怎么办?每次调整大小都需要重新渲染吗?我想我也需要对此进行反跳。恶心。

问题:

有没有更优雅的方式来实现这个目标?

半功能MCVE:

https://codepen.io/anon/pen/mjYzMM

class App extends React.Component {
  render() {
    return (
      <div>
        <Test message="Overflow Ellipsis" />
        <Test message="Fits" />
      </div>
    );
  }
}

class Test extends React.Component {
  constructor(props) {
    super(props);
    this.element = React.createRef();
  }
  componentDidMount() {
    this.forceUpdate();
  }

  doesTextFit = () => {
    if (!this.element) return false;
    if (!this.element.current) return false;
    console.log(
      "***",
      "offsetWidth: ",
      this.element.current.offsetWidth,
      "scrollWidth:",
      this.element.current.scrollWidth,
      "doesTextFit?",
      this.element.current.scrollWidth <= this.element.current.offsetWidth
    );

    return this.element.current.scrollWidth <= this.element.current.offsetWidth;
  };
  render() {
    return (
      <p
        className="collapse"
        ref={this.element}
        title={this.doesTextFit() ? "it fits!" : "overflow"}
      >
        {this.props.message}
      </p>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));
Run Code Online (Sandbox Code Playgroud)
.collapse {
    width:60px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
Run Code Online (Sandbox Code Playgroud)
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="container"></div>
Run Code Online (Sandbox Code Playgroud)

mka*_*man 5

因为很多人还在看这个问题。我终于弄清楚该怎么做了。我会尝试在某个时候将其重写为一个工作示例,但要点如下。

// Setup a ref
const labelRef = useRef(null);

// State for tracking if ellipsis is active
const [isEllipsisActive, setIsEllipsisActive] = useState(false);

// Setup a use effect
useEffect(() => {
    if(labelRef?.current?.offsetWidth < labelRef?.current?.scrollWidth) {
        setIsEllipsisActive(true);
    }
}, [labelRef?.current, value, isLoading]); // I was also tracking if the data was loading

// Div you want to check if ellipsis is active
<div ref={labelRef}>{value}</div>
Run Code Online (Sandbox Code Playgroud)

  • 对于多行文本,我还添加了offsetHeight和scrollHeight比较 if(elementRef?.current?.offsetHeight &lt; elementRef?.current?.scrollHeight || elementRef?.current?.offsetWidth &lt; elementRef?.current?.scrollWidth){setIsEllipsisActive(true );} (2认同)