javascript - 在React16中的长字符串中间添加省略号

标签 javascript string render react-16

我试图在字符串的中点添加省略号,但存在以下复杂情况:

  • 我不知道字符串有多长
  • 我只知道父元素的最大宽度和最小宽度
  • 该字符串可能适合也可能不适合其父字符串,并且不需要省略号

我有一个plunk here来说明它。该脚本仅假设一个实例,但您应该明白:

(function(){
    // variables
    var parent = document.querySelectorAll(".wrapper")[0],
    parentWidth = parent.clientWidth,x = 0, elem, hellip
    txtStr = document.querySelector("#shorten"),
    strWidth = txtStr.clientWidth,
    strTxt = txtStr.innerText,
    ending = document.createElement("span"),
    endTxt = strTxt.slice(Math.max(strTxt.length - (strTxt.length / 4))) || endTxt;
    txtStr.style.overflow = "hidden"
    txtStr.style.textOverflow = "ellipsis"
    ending.appendChild(document.createTextNode(endTxt))
    ending.classList.add("ellipsis")
    document.querySelectorAll(".wrapper")[0].appendChild(ending)
    var ell = function(a, b){
        if (a <= b){
            ending.classList.add("visible")
        }
        else {
            ending.classList.remove("visible")
        }
    }
    ell(parentWidth, strWidth) // We need to display any changes immediately
    window.onresize = function(){ // if the window is resized, we also need to display changes
        hellip = document.querySelectorAll(".ellipsis")[0].clientWidth
        parentWidth = parent.clientWidth
        // the use of 'calc()' is because the length of string in px is never known
        txtStr.style.width = "calc(100% - " + hellip + "px"
        ell(parentWidth, strWidth)
    }
})();

虽然有点笨拙,但演示了这个想法。

我在 React 16 中遇到的问题是,在我需要测量字符串以在末尾创建文本位时,字符串没有呈现。因此,当新节点创建时,它没有维度,并且无法测量,因为它不存在于 DOM 中。

该功能可以工作 - 有点像屏幕大小调整,但这不是重点。我需要让它在渲染时执行此操作。

实际的应用程序是专有的,我无法在此论坛中分享我的任何代码。

编辑:另一件事要记住(这里是教吸鸡蛋)是,在示例中,脚本仅在渲染 DOM 之后加载,因此所需的所有信息都是已经存在并且可以测量。

最佳答案

感谢所有看过此内容的人,但我设法解决了问题。

一旦我弄清楚了生命周期的技巧,它实际上仍然相当棘手。问题是测量原始文本字符串。现在回想起来,似乎微不足道。

本质上,我将一些元素作为 props 传递到组件中:一个 id、任何所需的填充、上下文所需的结束文本的长度以及文本(子级)。

一旦它们进入,我需要等待它被安装,直到我可以做任何事情,因为这一切都取决于正在渲染的 DOM,然后才能测量任何内容。因此,componentDidMount()和componentDidUpdate()是我感兴趣的阶段。componentWillUnmount()用于删除关联的事件监听器,在本例中是一个调整大小事件。

安装后,我可以获得测量所需的位:元素,重要的是它的父元素。

getElements(){
  return {
    parent: this.ellipsis.offsetParent,
    string: this.props.children
  }
}

然后,我需要确保我实际上可以测量元素,因此实现一些内联样式以实现这一点:

prepareParentForMeasure(){
  if(this.getElements().parent != null){
    this.getElements().parent.style.opacity = 0.001
    this.getElements().parent.style.overflow = 'visible'
    this.getElements().parent.style.width = 'auto'
  }
}

一旦获得这些尺寸,我就删除了样式。

此时,如果我继续沿着相同的路径前进,脚本将部分工作。然而,添加一个额外的元素作为指导是更重要的。

返回的元素被分成三个元素(span 标签),每个元素都有不同的用途。如果您愿意的话,有主要的文本,或者 this.props.children。这始终可用并且永远不会改变。接下来是文本的尾部,字符串末尾的“n”个字符,用于根据上下文显示字符串的结尾 - 这是一个“省略号”类,尽管省略号实际上是添加的到原始和第一个元素。第三个本质上与第一个完全相同,但它是隐藏的且不可交互,尽管它确实具有维度。这是因为前两个(在渲染时)具有不同的宽度,并且不能依赖它们,因为它们都会影响元素的宽度,而第三个则不会。

<Fragment>
  <span className='text'>{this.props.children}</span>
  <span className='ellipsis'>{this.tail()}</span>
  <span className='text guide' ref={node => this.ellipsis = node}>
    {this.props.children}</span>
</Fragment>

这些位于片段中,因此不需要周围的元素。

所以,我有周围父元素的宽度,还有文本元素的宽度(在第三个跨度中)。这意味着,如果我发现文本字符串比周围的包装器更宽,我会向“visible”的省略号范围添加一个类,并向“trimmed”的“text”元素添加一个类,我会在中间得到一个省略号的字符串,我使用调整大小事件来确保如果有人这样做,所有测量都会重新完成,并且内容会相应地重新计算和渲染。

关于javascript - 在React16中的长字符串中间添加省略号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48702618/

相关文章:

Javascript动态答案文本框

c# - 用户消息的复数性

c# - 如何在屏幕外渲染图表(来自 wpf 工具包)控件?

python - app.py 脚本中的几行我不明白

string - Rust 有类似 scanf 的东西吗?

javascript - 在 React 中映射过滤后的数组

c# - 允许和阻止 ASP.NET 中 javascript 的回发

javascript - Canvas 和 jQuery?

javascript - on 和 hover 不能一起工作

c - scanf 使程序崩溃并比较字符串 C