【问题标题】:How to calcuclate properties from element sizes in React?如何根据 React 中的元素大小计算属性?
【发布时间】:2021-03-24 08:01:57
【问题描述】:

我的页面上有一张卡片,其标题是用户名。名称有时比卡片长,之前的溢出是省略号,悬停时会出现工具提示以显示全名。现在应该以某种方式进行更改,如果它溢出,那么 texts letter-spacing 属性将一直减小到 -2,之后它将开始真正溢出并带有省略号。如何从封闭 div 的可用宽度计算值?或者应该如何实施。

当前状态:

对于可以符合字母间距的名称:-2

对于长名称:

对于简称:

注意,所有卡片的容器大小都相同!

【问题讨论】:

  • 一些描述单词的代码和图片会有所帮助。
  • 编辑中添加截图,希望更容易理解
  • 容器宽度会增加吗?因为我看到“for long names”卡片的宽度更长?
  • 不,它不是,它是一样的,抱歉截图不好,只是页面大小不同

标签: javascript css reactjs user-interface


【解决方案1】:

假设你的卡片组件是这样的

function Card({ name }) {
  return (
    <div className="card">
      <div className="card__pic"></div>
      <h3 className="card__name" ref={nameRef}>
        {name}
      </h3>
    </div>
  );
}

我们只需要包含名称的元素,即“card__name”。

  1. 访问“名称”元素。

要访问这个名称元素,我们必须使用useRef 钩子。以下是您将如何使用它。

function Card({ name }) {
  const nameRef = useRef(null);

  useEffect(() => {
    // nameRef.current is accessible here
  }, []);

  return (
    <div className="card">
      <div className="card__pic"></div>
      <h3 className="card__name" ref={nameRef}>
        {name}
      </h3>
    </div>
  );
}

我们必须将ref={refVariable} 传递给我们想要访问的元素。 refVariable 将在挂载后使用元素节点进行初始化,即我们可以在 useEffect 挂钩中使用它。

  1. 确定名称是否溢出。

现在我们有了元素,我们可以用它来检查里面的文本是否溢出。我创建了一个函数isTextOverflowingCard,我们将引用传递给我们在挂载后获得的元素。如果文本溢出则返回 true,否则返回 false。

function isTextOverflowingCard(textElement) {
  if (textElement.scrollWidth > textElement.clientWidth) {
    return true;
  }
  return false;
}

现在我们可以在 Card 内部使用这个函数,并根据它的返回值,有条件地添加一个类,该类将具有紧密的字母间距值。

function Card({ name }) {
  const nameRef = useRef(null);
  const [textOverflow, setTextOverflow] = useState(false);

  useEffect(() => {
    // nameRef.current is accessible here
    setTextOverflow(isTextOverflowingCard(nameRef.current));
  }, []);

  return (
    <div className="card">
      <div className="card__pic"></div>
      <h3 className={`card__name ${textOverflow ? 'card__name--tight-kerning' : ''}`} ref={nameRef}>
        {name}
      </h3>
    </div>
  );
}

在 CSS 中,

.card__name--tight-kerning {
  letter-spacing: -2px;
}

可以将useEffect改成useLayoutEffect,更适合这种dom相关的计算和应用于ui。

参考资料:

  1. Detect if text has overflown
  2. useEffect vs useLayoutEffect
  3. https://reactjs.org/docs/hooks-reference.html#useref

【讨论】:

    猜你喜欢
    • 2013-09-21
    • 2016-02-03
    • 2020-11-12
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 2016-01-22
    相关资源
    最近更新 更多