2012-03-20 118 views
38

我有一个路径列表(缺少一个更好的单词,也许面包屑跟踪描述他们更好)。某些值太长而无法在其父项中显示,因此我正在使用text-overflow: ellipsis。问题是重要的信息在右侧,所以我希望省略号出现在左侧。事情是这样的此ASCII艺术:左侧的文本溢出省略号

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

注意,第一行是足够短,所以它仍然是靠左对齐,但其他两个太长,会出现在左侧的省略号。

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

编辑:在这一点上,我正在寻找解决Chrome中的错误的工作,以防止RTL和LTR混合文档时出现错误。从一开始我就需要这些,我只是没有意识到这一点。

+1

Ouch,混合RTL和LTR语言?最近我有很多问题。当我将每个RTL和LTR元素分隔到不同的div中时,我发现了很多帮助。否则,这两种语言都会以一种相当奇怪的方式混合在一起...... – Zwik 2012-03-26 18:52:21

+1

FWI:我在chrome问题上打开了一个错误:http://code.google.com/p/chromium/issues/detail?id = 155836 – Mbrevda 2013-02-13 10:26:08

+0

[当需要使用正确的“文本溢出”时,“方向”设置为“rtl”](http://stackoverflow.com/questions/18532256/needs-use-right-text-overflow- when-direction-is-set-to-rtl) – 2013-08-30 15:20:09

回答

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

+1

我将您的解决方案进一步推向了一个新的阶段,因此它在裁剪元素的内部具有多个单独文本节点时起作用:http: //jsfiddle.net/bgmort/qSyBU/3/ – undefined 2012-10-24 18:33:57

+4

非常感谢Brian!我分叉你的代码,因为我需要的东西在开始时会用'...'代替,而且当窗口大小调整时,然后在窗口大小增加时将文本恢复到初始状态。这可能不是最优雅的,但是对于任何可能觉得它有用的人来说,这是一个分支:http://jsfiddle.net/sP9AE/1/ – Jimbo 2012-10-30 14:06:20

+0

非常好,@Jimbo。现在也许有人可以把它抽象成一个jQuery插件。我可能会在某个时间做... – undefined 2013-01-08 21:16:49

53

这样的事情怎么样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>​

+10

这很接近。在FF中看起来不错,但是在Chrome中它会渲染第二行和第三行错误。看起来像刚刚在省略号前面,然后在右侧剪辑。 – Hemlock 2012-03-20 19:43:21

+0

+1我太慢了。 – 2012-03-20 19:43:23

+0

@ Hemlock - 哦,根据你的例子,第二行的第一个元素和第三行的前四个元素应该被截断? – j08691 2012-03-20 19:49:11

0

根据您的编辑:

在这一点上我正在寻找一种解决在Chrome 阻止其正常显示,当一个文档的bug混合RTL 和LTR。那是我从一开始就真正需要的,我只是没有意识到这一点。

你有没有进去看了unicode-bidi CSS属性(见SitepointW3C)?我其实只是在another recent post上了解到了这一点。我的猜测是,你会想要使用embed值为主要网站相反的方向。因此,在j08691的回答中,它是direction: rtlunicode-bidi: embed添加到CSS。这应该解决您所遇到的“混合RTL和LTR”问题。

+0

我对此抱有很高的期望,但是我尝试过'unicode-bidi' [这里](http://jsfiddle.net/ZfbaD/9/)并没有运气。 – Hemlock 2012-03-27 00:07:05

+0

对不起。根据[在此](http://code.google.com/p/chromium/issues/detail?id=2821)(2008年最高,2011年底)的日期,这个问题('rtl'和'ellipsis')一段时间在Chrome中。它几乎看起来好像被解决了,然后可能重新露面,但很难说。 – ScottS 2012-03-27 02:58:49

+0

@ScottS确实存在一个错误,这里提出的问题:http://code.google.com/p/chromium/issues/detail?id=155836 – Mbrevda 2013-02-13 10:26:42

3

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

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; 

} 
+0

这很接近。这很奇怪,它如何在单词的开头添加省略号,但从最后修剪单词。 – Hemlock 2012-03-27 18:07:16

+0

这就是我的想法。 – HerrSerker 2012-03-27 20:34:51

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

Js可能需要解决这个问题。我不能使用这个答案,但因为我没有使用jquery,我相信测量是必要的。 – Hemlock 2012-03-30 17:55:21

+0

对'省略号'使用'\ u2026'可能更好,而不是'...' – Spooky 2014-11-17 20:48:08

1

为什么不直接使用direction:rtl;

+3

由于Chrome中的错误,RTL和LTR混合在一起。 – Hemlock 2014-06-05 13:54:57

1

使用@Hemlocks,@布赖恩莫特森和@吉博的解决方案,我已经建立了一个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

1

使用一个稍微复杂的标记(使用BDI标签和对额外的跨度省略号),我们可以在CSS中完全解决问题,完全不需要JS - 跨浏览器(IE,FF,Chrome)并且包括在右侧保留标点符号:

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

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

唯一的注意事项是:行的高度需要固定,背景颜色需要明确知道(继承将无法使用)。

1

如果你不在乎这些文本的索引,您可以使用此方法(它反转文本行):如果你在你的文字,除了有你<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