[常用组件]文本省略 + Tooltip提示

[常用组件]文本省略 + Tooltip提示

很常用就对了

单行省略

.text {
    width: 100px;
    text-overflow: ellipsis;
    overflow: hidden;
    word-break: break-all;
    white-space: nowrap;
}

多行省略

.text{
    width: 100px;
    display: -webkit-box;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

兼容性较好,Chrome20以上基本都OK

兼容性查询:https://caniuse.com/?search=-webkit-box

判断文本是否溢出

node.clientWidth < node.scrollWidth     // 单行
node.clientHeight < node.scrollHeight  // 多行

function isOverflowing(node: HTMLElement): boolean {
  if (!node) return false;
  const isSingleLine = node.offsetHeight === node.scrollHeight;
  if (isSingleLine) {
    return node.clientWidth < node.scrollWidth; // single line overflow
  } else {
    return node.clientHeight < node.scrollHeight; // multi-line overflow
  }
}

或者使用

function isSingleLineOverflowing(node: HTMLElement): boolean {
  if (!node) return false;
  const range = document.createRange();
  range.setStart(node, 0);
  range.setEnd(node, node.childNodes.length);
  const rangeWidth = range.getBoundingClientRect().width;
  return Math.round(rangeWidth) > node.offsetWidth;
}

溢出后文本省略 + 创建Tooltip

单行的

import { useState } from 'react';
import { Tooltip } from 'antd';

const MyComponent = () => {
  const [tooltipVisible, setTooltipVisible] = useState(false);

  const handleTooltipVisibleChange = (visible: boolean) => {
    setTooltipVisible(visible);
  };

  const handleMouseEnter = (e: any) => {
    const el = e.currentTarget || e.target;
    const range = document.createRange();
    range.setStart(el, 0);
    range.setEnd(el, el.childNodes.length);
    const rangeWidth = range.getBoundingClientRect().width;
    const isOverflow = Math.round(rangeWidth) > el.offsetWidth;

    if (isOverflow && !tooltipVisible) {
      setTooltipVisible(true);
    }
  };

  const handleMouseLeave = () => {
    setTooltipVisible(false);
  };

  return (
    <>
      <span onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
        My text here
      </span>
      <Tooltip
        title={text || e.target.__text}
        visible={tooltipVisible}
        placement="top"
        style={{ maxWidth: '500px', wordBreak: 'break-all' }}
        getPopupContainer={() => document.body}
        destroyTooltipOnHide={true}
        zIndex={999999}
        onVisibleChange={handleTooltipVisibleChange}
      />
    </>
  );
};

多行的

import { useState } from 'react';
import { Tooltip } from 'antd';

const MyComponent = () => {
  const [tooltipVisible, setTooltipVisible] = useState(false);

  const handleTooltipVisibleChange = (visible: boolean) => {
    setTooltipVisible(visible);
  };

  const determineOverflow = (el: HTMLElement) => {
    if (!el) return false;
    const isSingleLine = el.offsetHeight === el.scrollHeight;
    if (isSingleLine) {
      return el.clientWidth < el.scrollWidth; // single line overflow
    } else {
      return el.clientHeight < el.scrollHeight; // multi-line overflow
    }
  };

  const handleMouseEnter = (e: any) => {
    const el = e.currentTarget || e.target;
    const isOverflow = determineOverflow(el);

    if (isOverflow && !tooltipVisible) {
      setTooltipVisible(true);
    }
  };

  const handleMouseLeave = () => {
    setTooltipVisible(false);
  };

  return (
    <>
      <span onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
        My text here
      </span>
      <Tooltip
        title={text || e.target.__text}
        visible={tooltipVisible}
        placement="top"
        style={{ maxWidth: '500px', wordBreak: 'break-all' }}
        getPopupContainer={() => document.body}
        destroyTooltipOnHide={true}
        zIndex={999999}
        onVisibleChange={handleTooltipVisibleChange}
      />
    </>
  );
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值