左侧文本溢出省略号

我有一个路径列表(缺少一个更好的词,也许面包屑路径描述他们更好)。有些值太长,无法显示在它们的父级中,因此我使用 text-overflow: ellipsis。问题是重要的信息在右边,所以我希望省略号出现在左边。像这样的艺术品:

----------------------------
|first > second > third    |
|...second > third > fourth|
|...fifth > sixth > seventh|
----------------------------

注意,第一行足够短,因此它保持左对齐,但是另外两行太长,因此省略号出现在左侧。

我更喜欢只有 CSS 的解决方案,但是如果不能避免的话,JS 也可以。如果这个解决方案只能在 Firefox 和 Chrome 中使用,那也没关系。

编辑: 在这一点上,我正在寻找一个工作周围的错误,阻止它在 Chrome 正确呈现时,一个文档是混合 RTL 和 LTR。从一开始,这就是我真正需要的,只是我没有意识到。

42391 次浏览

像这样的 翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳翻译: 奇芳怎么样?它使用方向、文本对齐和文本溢出来获得左侧的省略号。根据 MDN,将来可能会用 left-overflow-type值指定左边的省略号,但是这仍然被认为是实验性的。

p {
white-space: nowrap;
overflow: hidden;
/* "overflow" value must be different from "visible" */
text-overflow: ellipsis;
width: 170px;
border: 1px solid #999;
direction: rtl;
text-align: left;
}
<p>first > second > third<br /> second > third > fourth > fifth > sixth<br /> fifth > sixth > seventh > eighth > ninth</p>​

根据你的编辑:

在这一点上,我正在寻找一个工作周围的错误,在 Chrome 当一个文档是混合 RTL 时,阻止它正确地呈现 和 LTR。从一开始这就是我真正需要的,我只是没有 意识到这一点。

您是否查看了 unicode-bidi css 属性(参见 站点W3C) ?其实我也是在 另一个最近的帖子上才知道的。我的猜测是,你会希望使用的 embed值,这些作品去相反的方向,以主要网站。因此,在 j08691的答案中,它是 direction: rtl,将 unicode-bidi: embed添加到 CSS。这应该可以解决您遇到的“混合 RTL 和 LTR”问题。

有点小问题,不过也许方向是对的

Http://jsfiddle.net/herrserker/zfbad/50/

$('.container')
.animate({'width': 450}, 4000)
.animate({'width': 100}, 4000)
.animate({'width': 170}, 4000)
.container {
white-space: nowrap;
overflow: hidden;              /* "overflow" value must be different from "visible" */
text-overflow: ellipsis;
width:170px;
border:1px solid #999;
direction:rtl;
}
.container .part {
direction:ltr;


}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<span class="part">second</span>
<span class="part">&gt;</span>
<span class="part">third</span>
<span class="part">&gt;</span>
<span class="part">fourth</span>
<span class="part">&gt;</span>
<span class="part">fifth</span>
<span class="part">&gt;</span>
<span class="part">sixth</span>
</div>

我将一些 JavaScript 放在一起,以正则化三个项,并在必要的地方添加省略号。这并没有明确地看有多少文本将适合在框中,但如果框是固定的,这可能不是一个问题。

<style>
p {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width:170px;
border:1px solid #999;
direction:rtl;
text-align:left;
}
</style>


<p>first &gt; second &gt; third<br />
second &gt; third &gt; fourth &gt; fifth &gt; sixth<br />
fifth &lt; sixth &lt; seventh &lt; eighth &lt; ninth</p>


<script>
var text = $( 'p' ).text(),
split = text.split( '\n' ),
finalStr = '';
for( i in split ){
finalStr = finalStr.length > 0 ? finalStr + '<br />' : finalStr;
var match = /(\w+\s?(<|>)?\s?){3}$/.exec( split[i] );
finalStr = finalStr + ( split[i].length > match[0].length ? '...' : '' ) + match[0];
}
$( 'p' ).empty().html( finalStr );
</script>

我最终不得不破解并用 JavaScript 做一些事情。我希望有人能想出一个万福玛利亚的 CSS 解决方案,但人们似乎只是赞成的答案,应该是正确的,如果它没有 Chrome 的错误。J08691可以有他的工作的赏金.

<html>
<head>
<style>
#container {
width: 200px;
border: 1px solid blue;
}


#container div {
width: 100%;
overflow: hidden;
white-space: nowrap;
}
</style>
<script>
function trimRows() {


var rows = document.getElementById('container').childNodes;
for (var i=0, row; row = rows[i]; i++) {
if (row.scrollWidth > row.offsetWidth) {
var textNode = row.firstChild;
var value = '...' + textNode.nodeValue;
do {
value = '...' + value.substr(4);
textNode.nodeValue = value;


} while (row.scrollWidth > row.offsetWidth);
}
}
}
</script>
</head>
<body onload='trimRows();'>
<div id="container" >
<div>first > second > third</div>
<div>second > third > fourth > fifth > sixth</div>
<div>fifth > sixth > seventh > eighth > ninth</div>​
</div>
</body>


</html>

小提琴

为什么不用 direction:rtl;

使用@Hemlock、@Brian Mortenson 和@Jimbo 的解决方案,我构建了一个 jQuery 插件来解决这个问题。

我还添加了对返回初始值的支持。而不是让它返回当前的 innerHTML。希望对某些人有用。

(function($) {


$.trimLeft = function(element, options) {


var trim = this;


var $element = $(element), // reference to the jQuery version of DOM element
element = element;    // reference to the actual DOM element


var initialText = element.innerHTML;


trim.init = function() {
overrideNodeMethod("html", function(){ return initialText; });
trimContents(element, element);
return trim;
};


trim.reset = function(){
element.innerHTML = initialText;
return trim;
};


//Overide .html() to return initialText.
var overrideNodeMethod = function(methodName, action) {
var originalVal = $.fn[methodName];
var thisNode = $element;
$.fn[methodName] = function() {
if (this[0]==thisNode[0]) {
return action.apply(this, arguments);
} else {
return originalVal.apply(this, arguments);
}
};
};


var trimContents = function(row, node){
while (row.scrollWidth > row.offsetWidth) {
var childNode = node.firstChild;
if (!childNode)
return true;
if (childNode.nodeType == document.TEXT_NODE){
trimText(row, node, childNode);
}
else {
var empty = trimContents(row, childNode);
if (empty){
node.removeChild(childNode);
}
}
};
};


var trimText = function(row, node, textNode){
var value = '\u2026' + textNode.nodeValue;
do {
value = '\u2026' + value.substr(4);
textNode.nodeValue = value;
if (value == '\u2026'){
node.removeChild(textNode);
return;
}
}
while (row.scrollWidth > row.offsetWidth);
};


trim.init();


};


$.fn.trimLeft = (function(options){
var othat = this;


var single = function(that){
if (undefined == $(that).data('trim')) {
var trim = new $.trimLeft(that, options);
$(that).data('trim', trim);
$(window).resize(function(){
$(that).each(function(){
trim.reset().init();
});
});
}
};


var multiple = function(){
$(othat).each(function() {
single(this);
});
};


if($(othat).length>1)
multiple(othat);
else
single(othat);


//-----------
return this;
});




})(jQuery);

启动使用:

//Call on elements with overflow: hidden and white-space: nowrap
$('#container>div').trimLeft();
//Returns the original innerHTML
console.log($('#test').html());

小提琴

使用一个稍微复杂一点的标记(使用 bdi-tag 和一个额外的 span 作为省略号) ,我们可以完全用 CSS 解决这个问题,根本不需要 JS ——跨浏览器(IE,FF,Chrome) ,包括保持句读在右边:

Http://jsbin.com/dodijuwebe/1/edit?html,css,output

当然,这是一种黑客技术,涉及到伪元素的优点。然而,我们的团队一直在生产中使用这些代码,我们没有遇到任何问题。

唯一需要注意的是: 行的高度需要固定,背景颜色需要显式知道(继承不起作用)。

如果你不关心这些文本的索引,你可以使用这个方法(它反转文本行) :

如果在你的文本中除了 <br>还有其他 HTML元素,你需要做一些安排来使用这个方法。

HTML 代码:

<p>first > second > third<br/>
second > third > fourth <br>
fifth > sixth > seventh</p>

CSS 代码:

p{
overflow: hidden;
text-overflow: ellipsis;
unicode-bidi: bidi-override;
direction: rtl;
text-align: left;
white-space: nowrap;
width: 140px;
}

JavaScript 代码

[].forEach.call(document.getElementsByTagName("p"), function(item) {


var str = item.innerText;


//Change the operators
str = str.replace(/[<>]/g, function(char){ return ({"<" : ">", ">" : "<"})[char] });


//Get lines
var lines = str.split(/\n/);


//Reverse the lines
lines = lines.map(function(l){ return l.split("").reverse().join("") });


//Join the lines
str = lines.join("<br>");


item.innerHTML = str;


});

Jsfiddle

这些解决方案解决了前面或后面的弱或中性 比迪字(如 /\~.等)(基本上是任何标点符号或特殊字符)被误解的问题。

CSS 解决方案

使用以下组合:

p {
direction: rtl;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* or pre (e.g. preserve multiple spaces) */
}
span {
direction: ltr;
unicode-bidi: bidi-override; /* or isolate, isolate-override, embed */
}
<p><span>/path/to/a/very/long/file.name</span></p>

<bdo> Solution

Another possibility uses the <bdo> Bidirectional Text Override element:

p {
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; /* or pre (e.g. preserve multiple spaces) */
}
<bdo dir="rtl">
<p>
<bdo dir="ltr">/path/to/a/very/long/file.name</bdo>
</p>
</bdo>