使用 React 显示基于子内容(innerHTML)的工具提示

Show tooltip based on contents of children (innerHTML) with React

我有一个名为 Row 的组件,它当前正在使用 text-overflow: ellipsis 来避免行在太长时换行。

这是我目前的情况:

function Row(props) {
    const { show=true, children } = props;
    
    const style = {
        display: show ? 'block' : 'none',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis'
    };
    
    const title = React.Children
      .map(children, c => c.toString()) // wat do?
      .join(' ');
      
    return (<div style={style} title={title}>{children}</div>);
}

const el = document.querySelector('#content');

const component = (<div style={{width:'200px'}}>
  <Row>This is the first one works and is very long.</Row>
  <Row>The second one works too.</Row>
  <Row>But <b>bold</b> children do <b>not</b> work properly.</Row>
  <Row show={false}>A hidden row.</Row>
</div>);

ReactDOM.render(component, el);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>

<h1>Hover over the rows below</h1>
<div id="content"></div>

title 属性可以处理我的工具提示,但我不知道如何在子节点不是文本节点时获取它们的内容。

我的下一个想法是,我需要等到子项被渲染到 DOM,然后添加一个 mouseover 事件来检索文本节点……但这似乎有点过分了.

如何获取子节点的内容作为文本节点并显示为工具提示?

我认为您可以通过检查 .map 中的每个子元素来解决此问题,如果它是对象,则抓取 props.children 并将其转换为字符串。

要使这项工作适用于深层嵌套 HTML,您需要递归。对元素是什么(当它不是字符串时)进行一些额外的检查也很好。

function Row(props) {
    const { show=true, children } = props;
    
    const style = {
        display: show ? 'block' : 'none',
        whiteSpace: 'nowrap',
        overflow: 'hidden',
        textOverflow: 'ellipsis'
    };
    
    const title = React.Children
      .map(children, c => {
        if (typeof c === 'string') {
          return c.toString()
        } else {
          return c.props.children.toString();
        }

      }) // wat do?
      .join(' ');
      
    return (<div style={style} title={title}>{children}</div>);
}

const el = document.querySelector('#content');

const component = (<div style={{width:'200px'}}>
  <Row>This is the first one works and is very long.</Row>
  <Row>The second one works too.</Row>
  <Row>But <b>bold</b> children do <b>not</b> work properly.</Row>
  <Row show={false}>A hidden row.</Row>
</div>);

ReactDOM.render(component, el);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.1/react-dom.min.js"></script>

<h1>Hover over the rows below</h1>
<div id="content"></div>