在 React16 中的长字符串中间添加一个省略号
Add an ellipsis to middle of long string in React16
我试图在字符串的中点添加一个省略号,但有以下问题:
- 不知道字符串要多长
- 我只知道父元素的max-width和min-width
- 字符串可能适合也可能不适合它的父级并且不需要省略号
我有一个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' 个字符数,用于根据上下文显示字符串的结尾 - 这是给定 class 的 'ellipsis',虽然省略号实际上是添加到原始和第一个元素。第三个本质上与第一个完全相同,但它是隐藏的且不可交互的,尽管它确实具有维度。这是因为前两个 - 在呈现时 - 具有不同的宽度并且不能依赖,因为两者都有助于元素的宽度,而第三个则没有。
<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' 的省略号范围内添加一个 class,并在 [=39] 的 'text' 元素中添加一个=],我在字符串中间得到一个省略号,我使用调整大小事件来确保如果有人这样做,所有测量都会重新完成,并且相应地重新计算和呈现内容。
我试图在字符串的中点添加一个省略号,但有以下问题:
- 不知道字符串要多长
- 我只知道父元素的max-width和min-width
- 字符串可能适合也可能不适合它的父级并且不需要省略号
我有一个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' 个字符数,用于根据上下文显示字符串的结尾 - 这是给定 class 的 'ellipsis',虽然省略号实际上是添加到原始和第一个元素。第三个本质上与第一个完全相同,但它是隐藏的且不可交互的,尽管它确实具有维度。这是因为前两个 - 在呈现时 - 具有不同的宽度并且不能依赖,因为两者都有助于元素的宽度,而第三个则没有。
<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' 的省略号范围内添加一个 class,并在 [=39] 的 'text' 元素中添加一个=],我在字符串中间得到一个省略号,我使用调整大小事件来确保如果有人这样做,所有测量都会重新完成,并且相应地重新计算和呈现内容。