2012-03-20 440 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