文本中间的省略号(Mac 风格)

IT技术 javascript jquery css truncation
2021-03-14 08:24:42

我需要"..."在可调整大小的元素中的文本中间实现省略号 ( )。是它可能的样子。所以,

"Lorem ipsum dolor sit amet. Ut ornare dignissim ligula sed commodo."

变成

"Lorem ipsum dolor sit amet ... commodo."

当元素被拉伸到文本的宽度时,我希望省略号消失。如何才能做到这一点?

6个回答

在 HTML 中,将完整值放在自定义 data-* 属性中,例如

<span data-original="your string here"></span>

然后分配loadresize事件侦听器的JavaScript函数,将读取原始数据属性,并将其放置在innerHTML您的跨度标签。以下是省略号函数的示例:

function start_and_end(str) {
  if (str.length > 35) {
    return str.substr(0, 20) + '...' + str.substr(str.length-10, str.length);
  }
  return str;
}

调整这些值,或者如果可能的话,使它们动态化,如果有必要针对不同的对象。如果您有来自不同浏览器的用户,您可以从 dom 中其他地方相同字体和大小的文本中窃取参考宽度。然后插值到要使用的适当数量的字符。

一个提示也是在 ... 或 who 消息上有一个 abbr 标签,使用户能够获得带有完整字符串的工具提示。

<abbr title="simple tool tip">something</abbr>
@user102465 你能分享一下最终的结果吗?谢谢!
2021-04-17 08:24:42
这最终成为我最终解决方案的最佳基础。加上几行额外的 JavaScript 代码,它完全符合我的要求。我决定使用“标题”而不是自定义标签,所以现在它可以自然地提供可访问性。感谢 Stefan、John 和 Kgiannakakis!
2021-04-18 08:24:42
是否只有 css 方法?在 UI 本身中修复它而不是使用 javsacript?
2021-05-03 08:24:42
您实际上可以str.substr(-10)用于第二部分。
2021-05-07 08:24:42

我想提出我解决这个问题的例子。

主要思想是将文本分成两个偶数部分(或者第一个更大,如果长度是奇数),其中一个末尾有省略号,另一个与text-overflow: clip.

因此,如果您想让 js 自动/通用,您需要做的就是拆分字符串并设置属性。

不过,它也有一些缺点。

  1. 没有很好的文字包装,甚至是字母(目前text-overflow: ''仅适用于 FF)
  2. 如果单词之间发生分裂 - 空格应该在第一部分。否则,它会崩溃。
  3. 字符串的末尾不应有任何感叹号,因为direction: rtl- 它们将被移动到字符串的左侧。我认为,可以通过将单词的正确部分放在标签中并将感叹号放在::after伪元素中来解决这个问题但我还没有让它正常工作。

但是,有了所有这些,对我来说看起来真的很酷,尤其是当您拖动浏览器的边框时,您可以轻松地在 jsfiddle 页面上执行此操作:https ://jsfiddle.net/extempl/93ymy3oL/ 或者只是在下面运行具有固定最大宽度的代码段。

剧透下的GIF:

动图

body {
  max-width: 400px;
}

span::before, span::after {
  display: inline-block;
  max-width: 50%;
  overflow: hidden;
  white-space: pre;
}

span::before {
  content: attr(data-content-start);
  text-overflow: ellipsis;
}

span::after {
  content: attr(data-content-end);
  text-overflow: '';
  direction: rtl;
}
<span data-content-start="Look deep into nature, and then you " 
      data-content-end=  "will understand everything better"></span>

<br>
<span data-content-start="https://www.google.com.ua/images/branding/g" 
      data-content-end=  "ooglelogo/2x/googlelogo_color_272x92dp.png"></span>

text-overflow: '';chrome有解决方法吗?不支持字符串作为值;
2021-04-21 08:24:42
@jaysonder 不幸的是,到目前为止还没有仅 css 的解决方法。它仍然只适用于 FF:developer.mozilla.org/en-US/docs/Web/CSS/...
2021-04-21 08:24:42
上面的代码片段似乎在 chrome 中运行良好,但文本剪辑在后半部分看起来有点有趣。
2021-05-12 08:24:42

所以我的同事想出了一个不使用额外 dom 元素的解决方案。我们检查div是否溢出并添加最后n个字符的数据属性。其余的在css中完成。

这是一些HTML:

<div class="box">
    <div class="ellipsis" data-tail="some">This is my text it is awesome</div>
</div>
<div class="box">
    <div class="ellipsis">This is my text</div>
</div>

和CSS:

.box {
    width: 200px;
}

.ellipsis:before {
    float: right;
    content: attr(data-tail);
}

.ellipsis {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
}

这是强制性的 jsfiddle:http : //jsfiddle.net/r96vB/1/

差不多,但是每次盒子宽度变化时都需要执行JS,否则:after内容卡住:(
2021-04-19 08:24:42
非常好的解决方案,但不幸的是它在 Firefox 34(文本重叠)和 IE < 10(不支持的方法 querySelector)中不起作用
2021-04-24 08:24:42
我喜欢这个解决方案。适用于 Safari (mac)、FF 57、Edge 和 Chrome 66。
2021-05-08 08:24:42

以下 Javascript 函数将执行中间截断,如 OS X:

function smartTrim(string, maxLength) {
    if (!string) return string;
    if (maxLength < 1) return string;
    if (string.length <= maxLength) return string;
    if (maxLength == 1) return string.substring(0,1) + '...';

    var midpoint = Math.ceil(string.length / 2);
    var toremove = string.length - maxLength;
    var lstrip = Math.ceil(toremove/2);
    var rstrip = toremove - lstrip;
    return string.substring(0, midpoint-lstrip) + '...' 
    + string.substring(midpoint+rstrip);
}       

它将用省略号替换中间的字符。我的单元测试显示:

var s = '1234567890';
assertEquals(smartTrim(s, -1), '1234567890');
assertEquals(smartTrim(s, 0), '1234567890');
assertEquals(smartTrim(s, 1), '1...');
assertEquals(smartTrim(s, 2), '1...0');
assertEquals(smartTrim(s, 3), '1...90');
assertEquals(smartTrim(s, 4), '12...90');
assertEquals(smartTrim(s, 5), '12...890');
assertEquals(smartTrim(s, 6), '123...890');
assertEquals(smartTrim(s, 7), '123...7890');
assertEquals(smartTrim(s, 8), '1234...7890');
assertEquals(smartTrim(s, 9), '1234...67890');
assertEquals(smartTrim(s, 10), '1234567890');
assertEquals(smartTrim(s, 11), '1234567890');
这很好,并且按描述工作,但是我需要使输出字符串“可拉伸”,以便根据一个人的视口大小确定截断。大屏幕——无截断,窄屏——使用动态计算的字符数截断字符串以获得最佳匹配。
2021-04-23 08:24:42
您必须将事件处理程序附加到其容器,然后它会计算与容器宽度属性相关的适当 maxLength。如果您的字体系列是等宽的,这将很容易;如果成比例,那么您需要进行试验以获得正确的启发式方法。
2021-04-27 08:24:42
需要指出的是,这仅适用于固定宽度字体显示。在可变宽度字体上,文本的显示长度与字符长度不完全相关。
2021-04-27 08:24:42

这在游戏中可能有点晚了,但我一直在寻找解决方案,一位同事提出了一个非常优雅的解决方案,我将分享。它需要一些 JS,但不是很多。

想象一下,您有一个div尺寸需要将标签放入:

<div style="width: 200px; overflow: hidden"></div>

现在,你有一个函数,它需要两个参数:一个带有标签的字符串,以及一个 DOM 元素(this div)来适应它:

function setEllipsisLabel(div, label) 

您要做的第一件事是span使用此标签创建一个,并将其放入div

var span = document.createElement('span');
span.appendChild(document.createTextNode(label));
span.style.textOverflow = 'ellipsis';
span.style.display = 'inline-block';
div.appendChild(span);

我们将该text-overflow属性设置为“省略号”,以便在文本被截断时,在末尾添加一个漂亮的“...”来说明这一点。我们还设置display为“inline-block”,以便这些元素具有我们可以稍后操作的真实像素尺寸。到目前为止,没有什么是我们用纯 CSS 做不到的。

但是我们想要中间的省略号。首先,我们应该找出我们是否需要它......这可以通过比较div.clientWidth完成span.clientWidth- 只有当 thespandiv.时才需要省略号

如果我们确实需要省略号,让我们先说我们想要在单词末尾显示固定数量的字符 - 比如说 10。所以让我们创建一个仅包含标签的最后 10 个字符的跨度,并将其粘贴到分区:

var endSpan = document.createElement('span');
endSpan.style.display = 'inline-block';
endspan.appendChild(document.createTextNode(label.substring(label.length - 10)));
div.appendChild(endSpan);

现在,让我们覆盖原始的宽度span以适应新的宽度

span.style.width = (div.clientWidth - endSpan.clientWidth) + 'px';

因此,我们现在有一个 DOM 结构,看起来像这样:

<div style="width: 200px; overflow: hidden">
   <span style="display: inline-block; text-overflow: ellipsis; width: 100px">
      A really long label is shown in this span
   </span>
   <span style="display: inline-block"> this span</span>
</div>

由于第一spantext-overflow设置为“省略号”,则显示“......”结尾,随后是第二跨度的10个字符,导致示出的中间大约省略号div

您也不需要为 endSpan 硬编码 10 个字符的长度:这可以通过计算span的初始宽度与 的初始宽度div的比率,从标签的长度中减去适当的比例并除以 2来近似