文本溢出省略号在左侧

我有一个path列表(因为缺less一个更好的词,也许面包屑跟踪描述他们更好)。 其中一些值太长,无法在其父项中显示,所以我正在使用text-overflow: ellipsis 。 问题是重要的信息在右边,所以我想省略号出现在左边。 像这样的ascii艺术:

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

请注意,第一行是足够短的,所以它保持左alignment,但另外两个太长,所以省略号出现在左侧。

我更喜欢一个CSS唯一的解决scheme,但JS是好的,如果它无法避免。 如果该解决scheme只适用于Firefox和Chrome,则可以。

编辑: 在这一点上,我正在寻找一种解决scheme,以防止在文档混合RTL和LTR时正确呈现的Chrome中的错误。 从一开始我就是这么想的,我只是没有意识到这一点。

怎么样这样的jsFiddle ? 它使用方向,文本alignment和文本溢出来获取左边的省略号。 根据MDN的说法,在left-overflow-type值中可能会指定左边的省略号,但它仍然是实验性的。

CSS:

 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; } 

HTML:

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

我终于不得不破解并在JavaScript中做一些事情。 我希望有人能够提出一个骇人听闻的CSS解决scheme,但人们似乎只是在投票答案,如果不是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> 

小提琴

这是一个小小的错误,但也许是一个正确的方向点

http://jsfiddle.net/HerrSerker/ZfbaD/50/

 <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> 

 ​.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; } 

为什么不只是使用direction:rtl;

使用@Hemlocks,@Brian Mortenson和@ Jimbo的解决scheme,我已经构build了一个jQuery插件来解决这个问题。

我还添加了使用.html()返回初始值的支持,而不是返回当前的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和省略号的额外跨度),我们可以在CSS中完全解决问题,在所有跨浏览器(IE,FF,Chrome)中都不需要JS,并且包括标点符号标记在右边:

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

诚然,这是一个黑客行为,涉及伪元素善良。 然而,我们的团队已经在生产中使用这个代码,我们没有任何问题。

唯一的注意事项是:行的高度需要固定,背景颜色需要明确知道(inheritance将不起作用)。

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

如果您在文本中还有除了<br>之外的其他HTML元素<br>需要对此方法进行一些安排。

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

根据您的编辑:

在这一点上,我正在寻找解决Chrome中的错误,以防止RTL和LTR混合文档时,它正常渲染。 从一开始我就是这么想的,我只是没有意识到这一点。

你有没有看过unicode-bidi css属性(参见Sitepoint或W3C )? 我其实刚刚在最近的另一篇文章中了解到了这一点。 我的猜测是,你会想要使用embed值为主要网站相反的方向。 所以在j08691的回答是什么direction: rtl add unicode-bidi: embed到CSS中。 这应该解决您所遇到的“混合RTL和LTR”问题。

我把一些JavaScript组合在一起,将三个项目重新排列,并在需要的地方添加省略号。 这并没有明确地看看有多less文字会放在盒子里,但是如果盒子是固定的,这可能不是问题。

 <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>