左侧的文本溢出省略号

时间:2012-03-20 19:20:51

标签: javascript html css css3

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

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

请注意,第一行足够短,因此它保持左对齐,但其他两行太长,因此省略号显示在左侧。

我更喜欢只有CSS的解决方案,但如果无法避免,JS就可以了。如果该解决方案仅适用于Firefox和Chrome,则可以。

编辑:此时我正在寻找解决Chrome中的错误的方法,以防止文档混合使用RTL和LTR时正确呈现错误。这就是我从一开始就真正需要的,我只是没有意识到这一点。

9 个答案:

答案 0 :(得分:73)

jsFiddle 这样的内容怎么样?它使用方向,文本对齐和文本溢出来获取左侧的省略号。根据{{​​3}},可能有可能在未来使用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>​

答案 1 :(得分:14)

我终于不得不破解并用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>

Fiddle

答案 2 :(得分:4)

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

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>

答案 3 :(得分:3)

为什么不使用direction:rtl;

答案 4 :(得分:1)

使用@Hemlocks,@ Brian Mortenson和@Jimbo的解决方案,我已经构建了一个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());

fiddle

答案 5 :(得分:1)

使用稍微复杂的标记(使用bdi-tag和省略号的额外范围),我们可以在CSS中完全解决问题,根本不需要JS - 跨浏览器(IE,FF,Chrome)和包括在右边保留标点符号:

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

当然,这是一种涉及伪元素善意的黑客行为。但是,我们的团队一直在使用此代码进行生产,我们没有任何问题。

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

答案 6 :(得分:1)

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

  

如果您的文本中除$ids_emp = "1"; $date1 = "2016/01/01"; $date2 = "2016/02/01"; $query2 = "SELECT d.*, e.EMP_FIRST_NAME, a.ATTENDANCE_TYPE_TITLE FROM daily_sheet d INNER JOIN attendance_type a ON a.ATTENDANCE_TYPE_ID = d.ATTENDANCE_TYPE_ID INNER JOIN ids_employ e ON e.EMP_ID = d.EMP_ID WHERE d.EMP_ID = 1"; if($ids_emp != '') { $query2 .= " AND e.EMP_ID = '$ids_emp'"; } if($date1 != '' && $date2 != '') { $query2 .= " AND d.DATE >= '$date1' AND d.DATE <= '$date2'"; } 之外的其他HTML个元素,您需要做出一些安排来使用此方法。

HTML code:

<br>

CSS代码:

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

JavaScript代码

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

jsfiddle

答案 7 :(得分:0)

根据您的修改:

  

此时我正在寻找解决Chrome中的错误的方法   当文档混合RTL时阻止它正确呈现   和LTR。这就是我从一开始就真正需要的,我只是没有   实现它。

您是否查看了unicode-bidi css属性(请参阅SitepointW3C)?我实际上只是在another recent post上了解到这一点。我的猜测是,您希望将embed值用于与主站点相反方向的那些块。所以在j08691的答案中,direction: rtlunicode-bidi: embed添加到CSS。这应解决您遇到的“混合RTL和LTR”问题。

答案 8 :(得分:0)

我将一些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>