如何在从左到右的元素开头添加文本溢出省略号

问题描述 投票:0回答:10

我有一个路径列表(由于缺乏更好的词,也许面包屑路径可以更好地描述它们)。有些值太长而无法在其父级中显示,因此我使用

text-overflow: ellipsis
。问题是重要信息位于右侧,因此我希望省略号出现在左侧。像这样的 ascii 艺术:

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

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

我更喜欢仅 CSS 的解决方案,但如果无法避免,JS 也可以。如果该解决方案仅适用于 Firefox 和 Chrome,那也没关系。

编辑:此时,我正在寻找解决 Chrome 中 bug 的方法,当文档混合 RTL 和 LTR 时,这些 bug 会阻止 Chrome 正确呈现。这就是我从一开始就真正需要的,只是我没有意识到。

javascript html css overflow
10个回答
118
投票

像这样的jsFiddle怎么样?它使用方向、文本对齐和文本溢出来获得左侧的省略号。根据 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>


14
投票

我终于不得不破解 JavaScript 了:

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

JSFiddle


8
投票

为什么不直接使用

direction:rtl;


7
投票

有点问题,但也许是正确的方向

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>


7
投票

双翻转解决方案

仅使用 CSS 的跨浏览器解决方案。它需要反转文本(通过服务器或使用 JavaScript),然后通过 CSS 将每个字符翻转为其镜像,然后将整个文本翻转为其镜像。步骤的可视化如下:

  • eman.elif/gnol/yrev/a/ot/htap/
    (向后文本)
  • eman.elif/gnol/yrev/...
    (添加省略号)
  • .../very/long/file.name
    (全文翻转)

p {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transform: rotateY(180deg);
}
span {
  display: inline-block;
  transform: rotateY(180deg);
}
<p><span>e</span><span>m</span><span>a</span><span>n</span><span>.</span><span>e</span><span>l</span><span>i</span><span>f</span><span>/</span><span>g</span><span>n</span><span>o</span><span>l</span><span>/</span><span>y</span><span>r</span><span>e</span><span>v</span><span>/</span><span>a</span><span>/</span><span>o</span><span>t</span><span>/</span><span>h</span><span>t</span><span>a</span><span>p</span><span>/</span></p>

以下解决方案使用

rtl
,同时解决前面或结尾的弱或中性 BiDi 字符的误解问题,例如
/
\
~
.
等(基本上是任何标点符号或特殊符号)字符)。

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>
双向文本覆盖元素:

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>


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());

小提琴


1
投票

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

如果您的文本中除了

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


0
投票

根据您的编辑:

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

您是否研究过

unicode-bidi
css 属性(参见 SitepointW3C)?事实上,我自己刚刚在最近的另一篇文章上了解到了这一点。我的猜测是,您可能希望对那些与主站点相反方向的片段使用
embed
值。因此,在 j08691 的答案中,将
direction: rtl
添加到 CSS 中。这应该可以解决您遇到的“混合 RTL 和 LTR”问题。
    


0
投票

unicode-bidi: embed



0
投票

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

当然,这是一种黑客行为,涉及伪元素的优点。但是,我们的团队一直在生产中使用此代码,并且没有遇到任何问题。

唯一的注意事项是:需要固定线条的高度,并且需要明确了解背景颜色(继承不起作用)。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.