简体   繁体   English

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

[英]How can I conditionally show title tooltip if CSS ellipsis is active within a React component

Problem :问题

I'm looking for a clean way to show a title tooltip on items that have a CSS ellipsis applied.我正在寻找一种干净的方法来显示应用了 CSS 省略号的项目的标题工具提示。 (Within a React component) (在 React 组件中)

What I've tried:我试过的:

I setup a ref, but it doesn't exist until componentDidUpdate, so within componentDidUpdate I forceUpdate.我设置了一个 ref,但它在 componentDidUpdate 之前不存在,所以在 componentDidUpdate 中我强制更新。 (This needs some more rework to handle prop changes and such and I would probably use setState instead.) This kind of works but there are a lot of caveats that I feel are unacceptable. (这需要更多的返工来处理 prop 更改等,我可能会改用 setState。)这种方法可行,但有很多我觉得不可接受的警告。

  1. setState/forceUpdate - Maybe this is a necessary evil setState/forceUpdate - 也许这是一个必要的邪恶
  2. What if the browser size changes?如果浏览器大小发生变化怎么办? Do I need to re-render with every resize?每次调整大小都需要重新渲染吗? I suppose I'd need a debounce on that as well.我想我也需要去抖动。 Yuck.呸。

Question:问题:

Is there a more graceful way to accomplish this goal?有没有更优雅的方式来实现这个目标?

Semi-functional MCVE:半功能 MCVE:

https://codepen.io/anon/pen/mjYzMM 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"));
 .collapse { width:60px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
 <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>

I use this framework agnostic snippet to this.我对此使用了这个与框架无关的片段。 Just include it on your page and see the magic happen;)只需将它包含在您的页面上,就会看到奇迹发生;)

(function() {
  let lastMouseOverElement = null;
  document.addEventListener("mouseover", function(event) {
    let element = event.target;
    if (element instanceof Element && element != lastMouseOverElement) {
        lastMouseOverElement = element;
        const style = window.getComputedStyle(element);
        const whiteSpace = style.getPropertyValue("white-space");
        const textOverflow = style.getPropertyValue("text-overflow");
        if (whiteSpace == "nowrap" && textOverflow == "ellipsis" && element.offsetWidth < element.scrollWidth) {
            element.setAttribute("title", element.textContent);
        } else {
            element.removeAttribute("title");
        }
    }
  });
})();

From: https://gist.github.com/JoackimPennerup/06592b655402d1d6181af32def40189d来自: https://gist.github.com/JoackimPennerup/06592b655402d1d6181af32def40189d

Since a lot of people are still viewing this question.因为很多人还在看这个问题。 I did finally figure out how to do it.我终于知道怎么做了。 I'll try to rewrite this into a working example at some point but here's the gist.我会在某个时候尝试将其重写为一个工作示例,但这是要点。

// 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM