我需要在可调整大小的元素中的文本中间实现省略号("..."
)。 Here可能是它的样子。所以,
"Lorem ipsum dolor sit amet. Ut ornare dignissim ligula sed commodo."
变为
"Lorem ipsum dolor sit amet ... commodo."
当元素伸展到文本的宽度时,我希望省略号消失。怎么办呢?
答案 0 :(得分:27)
在HTML中,将完整值放在自定义data- *属性中,如
<span data-original="your string here"></span>
然后将load
和resize
个事件侦听器分配给JavaScript函数,该函数将读取原始数据属性并将其放在span标记的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中其他位置的相同字体和大小从文本中窃取参考宽度。然后插入适当数量的字符以供使用。
提示也要在...上添加一个abbr-tag,或者使用户能够获得完整字符串的工具提示的消息。
<abbr title="simple tool tip">something</abbr>
答案 1 :(得分:20)
我想提出解决这个问题的例子。
主要思想是将文本分成两个偶数部分(或者第一个更大,如果长度是奇数),其中一个最后有省略号,另一个右对齐text-overflow: clip
。
所以你需要用js做的,如果你想让它自动/通用 - 就是分割字符串和设置属性。
但是,它有一些缺点。text-overflow: ''
目前仅适用于FF)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>
答案 2 :(得分:9)
所以我的同事提出了一个不使用额外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/
答案 3 :(得分:6)
以下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');
答案 4 :(得分:3)
你不能用CSS做到这一点。问题是HTML和CSS应该在各种浏览器和字体中工作,几乎不可能以一致的方式计算字符串的宽度。这是idea,可能会对您有所帮助。但是,您需要多次这样做,直到找到具有适当宽度的字符串。
答案 5 :(得分:3)
这可能在游戏中有点晚了,但我想找到一个解决方案,一位同事建议一个非常优雅的,我将分享。它需要一些JS,但不是很多。
想象一下,你需要一个div
大小的标签:
<div style="width: 200px; overflow: hidden"></div>
现在,你有一个函数,它将采用两个参数:一个带有标签的字符串和一个DOM元素(这个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
设置为“内联块”,以便这些元素具有我们稍后可以操作的实际像素尺寸。到目前为止,我们无法用纯CSS做任何事情。
但是我们想要省略号。首先,我们应该知道我们是否需要它...这可以通过比较div.clientWidth
到span.clientWidth
来完成 - 只有在span
宽于{{div
时才需要省略号。 1}}。
如果我们确实需要一个省略号,那么我们首先要说我们想要在单词末尾显示固定数量的字符 - 比如10.所以让我们创建一个只包含标签最后10个字符的span,并且进入div:
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>
因为第一个span
将text-overflow
设置为“省略号”,所以最后会显示“...”,然后是第二个跨度的10个字符,从而显示省略号大约在div
的中间。
你也不需要对endSpan的10个字符长度进行硬编码:这可以通过计算span
的初始宽度与div
的宽度的比率来近似,减去相应的从标签长度开始的比例除以2。
答案 6 :(得分:2)
经过对弹性盒子的一些研究后,我发现这个纯CSS解决方案,我相信这很酷。
<div style="width:100%;border:1px solid green;display:inline-flex;flex-wrap:nowrap;">
<div style="flex: 0 1 content;text-overflow: ellipsis;overflow:hidden;white-space:nowrap;"> Her comes very very very very very very very very very very very very very very very very very very very long </div>
<div style="flex: 1 0 content;white-space:nowrap;"> but flexible line</div>
</div>
答案 7 :(得分:1)
这是我能找到的最短的一位用......取代中间的3个字符。
function shorten(s, max) {
return s.length > max ? s.substring(0, (max / 2) - 1) + '...' + s.substring(s.length - (max / 2) + 2, s.length) : s
}
答案 8 :(得分:1)
此解决方案是上述解决方案的组合,将最后一个完整的单词放在缩短的文本的末尾。但是,如果最后一个单词的长度大于可用空间的三分之一,则该单词也会从左侧缩短。如果找到破折号(“-”),则将其剪切掉,如果没有,则将其剪切掉。
function truncate(text, textLimit) {
if (!text) return text;
if (textLimit < 1) return string;
if (text.length < textLimit) return text;
if (textLimit === 1) return text.substring(0,1) + '...';
/* extract the last word */
var lastPart = text.slice( string.lastIndexOf(' ')+1 );
/* if last word is longer then a third of the max available space
cut it from the left */
var lastPartLimit = Math.ceil(textLimit / 3);
if(lastPart.length > lastPartLimit) {
var truncatedLastPart = lastPart;
/* Try to find a dash and cut the last word there */
var lastDashPart = text.slice( text.lastIndexOf('-')+1 );
if(lastDashPart.length < lastPartLimit){
truncatedLastPart = lastDashPart;
}
/* If the last part is still to long or not available cut it anyway */
if(truncatedLastPart.length > lastPartLimit) {
var lastIndex = lastPart.length - lastPartLimit;
truncatedLastPart = lastPart.substring( lastIndex );
}
lastPart = truncatedLastPart;
}
var dots = '... ';
var firsPartLength = textLimit - lastPart.length - dots.length;
return text.substring(0, firstPartLength) + dots + lastPart;
}
console.log( truncate("New York City", 10) ); // Ne... City (max of 10 characters)
console.log( truncate("New York Kindergarden", 14) ); // Ne...ergarden (max of 14 characters, last word gets cut from the left by a third)
console.log( truncate("New York Kinder-garden", 14) ); // Ne...garden (max of 14 characters, last word gets cut by the dash from the left)
答案 9 :(得分:0)
我刚创建了一个可以在中间,近端和末端修剪的功能,但还没有经过测试,因为我最终需要在服务器端
//position acceptable values : middle, end, closeEnd
function AddElipsis(input, maxChars, position) {
if (typeof input === 'undefined') {
return "";
}
else if (input.length <= maxChars) {
return input;
}
else {
if (position == 'middle') {
var midPos = Math.floor(maxChars / 2) - 2;
return input.substr(0, midPos) + '...' + input.substr(input.length - midPos, input.length);
}
else if (position == 'closeEnd') {
var firstPart = Math.floor(maxChars * 0.80) - 2;
var endPart = Math.floor(maxChars * 0.20) - 2;
return input.substr(0, firstPart) + '...' + input.substr(input.length - endPart, input.length);
}
else {
return input.substr(0, maxChars - 3) + '...';
}
}
}
答案 10 :(得分:0)
另一个刺:
function truncate( str, max, sep ) {
max = max || 10;
var len = str.length;
if(len > max){
sep = sep || "...";
var seplen = sep.length;
if(seplen > max) { return str.substr(len - max) }
var n = -0.5 * (max - len - seplen);
var center = len/2;
return str.substr(0, center - n) + sep + str.substr(len - center + n);
}
return str;
}
console.log( truncate("123456789abcde") ); // 123...bcde (using built-in defaults)
console.log( truncate("123456789abcde", 8) ); // 12...cde (max of 8 characters)
console.log( truncate("123456789abcde", 12, "_") ); // 12345_9abcde (customize the separator)
答案 11 :(得分:0)
这将使您可以更好地控制省略号和占位符文本的位置:
function ellipsis(str, maxLength, ellipsisLocationPercentage,placeholder) {
/*
ARGUMENTS:
str - the string you want to maninpulate
maxLength - max number of characters allowed in return string
ellipsisLocationPercentage (optional) - How far (percentage wise) into the return string you want the ellipses to be placed
Examples:
.85 : This is a very long string. This is a very long string. This is a very long string. This is a ver[...]very long string.
.25 : This is a very long string. [...]g. This is a very long string. This is a very long string. This is a very long string.
placeholder (optional) - this will be used to replace the removed substring. Suggestions : '...', '[..]', '[ ... ]', etc....
*/
if(ellipsisLocationPercentage == null || isNaN(ellipsisLocationPercentage) || ellipsisLocationPercentage >= 1 || ellipsisLocationPercentage <= 0){
//we've got null or bad data.. default to something fun, like 85% (that's fun, right??)
ellipsisLocationPercentage = .85;
}
if(placeholder == null || placeholder ==""){
placeholder = "[...]";
}
if (str.length > (maxLength-placeholder.length)) {
//get the end of the string
var beginning = str.substr(0, (maxLength - placeholder.length)*ellipsisLocationPercentage );
var end = str.substr(str.length-(maxLength - placeholder.length) * (1-ellipsisLocationPercentage));
return beginning + placeholder + end;
}
return str;
}
您可以致电:
来调用此功能ellipsis("This is a very long string. Be Scared!!!!", 8);//uses default values
ellipsis("This is a very long string. Be Scared!!!!", 8,.5);//puts ellipsis at half way point
ellipsis("This is a very long string. Be Scared!!!!", 8,.75,'<..>');//puts ellipsis at 75% of the way into the string and uses '<..>' as the placeholder
答案 12 :(得分:0)
为了做一个干净的剪辑,并在缩短文本的末尾有一个完整的单词,我使用了以下功能。
function prepareText(text){
var returnString = text;
var textLimit = 35;
if(text.length > textLimit){
var lastWord = text.slice( text.lastIndexOf(' ')+1 );
var indexFromEnd = lastWord.length;
var ellipsis = '... ';
returnString = text.slice(0, textLimit - indexFromEnd - ellipsis.length);
returnString = returnString + ellipsis + lastWord;
}
return returnString;
}
$('#ex1Modified').html( prepareText( $('#ex1').html() ) );
$('#ex2Modified').html( prepareText( $('#ex2').html() ) );
$('#ex3Modified').html( prepareText( $('#ex3').html() ) );
body{color:#777; font-family: sans-serif;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>Shortened Quotes from Albert Einstein</h2>
<div id="ex1">"The true sign of intelligence is not knowledge but imagination."</div>
<div id="ex1Modified"></div>
<br>
<div id="ex2">"Look deep into nature, and then you will understand everything better."</div>
<div id="ex2Modified"></div>
<br>
<div id="ex3">"You can't blame gravity for falling in love."</div>
<div id="ex3Modified"></div>
答案 13 :(得分:0)
这是一个优雅的解决方案:
function truncateMiddle(word) {
const tooLongChars = 15; // arbitrary
if (word.length < tooLongChars) {
return word;
}
const ellipsis = '...';
const charsOnEitherSide = Math.floor(tooLongChars / 2) - ellipsis.length;
return word.slice(0, charsOnEitherSide) + ellipsis + word.slice(-charsOnEitherSide);
}
答案 14 :(得分:0)
我在这里看到的所有解决方案都没有考虑到不同字符的宽度不同。 我的解决方案考虑了这一点。基本上,它将文本删除一个字符,直到适合为止,看看:
const span = document.getElementById("span");
const div = document.getElementById("div");
const originalText = span.textContent;
const textLength = originalText.length;
let part1 = originalText.substr(0, Math.floor(textLength/2));
let part2 = originalText.substr(Math.floor(textLength/2));
let trimPart1 = true;
while (span.clientWidth > div.clientWidth) {
if (trimPart1) {
part1 = part1.substr(0, part1.length - 1);
} else {
part2 = part2.substr(-1 * (part2.length - 1));
}
span.textContent = part1 + "..." + part2;
trimPart1 = !trimPart1;
}
<div id="div" style="overflow: hidden; width: 200px; white-space: nowrap;">
<span id="span" style="display: inline-block">this is a quite long text that has some words and I want it to be split in half</span>
</div>
https://jsfiddle.net/maxim_mazurok/oujctpz8/56/
Mac的Finder以相同的方式工作,它首先尝试剥离左侧部分,然后剥离右侧部分。因此,就像我的解决方案一样,它可能有WWWW...WWWWW
。
虽然它不是最有效的一种。也许,使用虚拟DOM或canvas可以更好地优化性能。
答案 15 :(得分:0)
这是我的看法 - 一个仅适用于 CSS 的解决方案,遗憾的是目前仅适用于 Firefox:
div {
width: 20em;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
text-overflow: " … is also your text.";
}
<div>Here's the long string of letters that accidentally is also your text.</div>
如果您需要动态文本,您可以直接在元素上指定第二个 text-overflow
声明。不支持这种语法的浏览器(Chrome,特别是 :-)将回退到普通的旧省略号。