2012-03-20 42 views
38

Tôi có một danh sách các đường dẫn (vì thiếu từ tốt hơn, có thể là những mẩu bánh mì vụn mô tả chúng tốt hơn). Một số giá trị quá dài để hiển thị trong bố mẹ nên tôi đang sử dụng text-overflow: ellipsis. Vấn đề là thông tin quan trọng ở bên phải, vì vậy tôi muốn dấu chấm lửng xuất hiện ở bên trái. Một cái gì đó như thế này nghệ thuật ascii này:Dấu chấm lửng tràn văn bản ở bên trái

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

Lưu ý rằng hàng đầu tiên đủ ngắn để nó được căn trái, nhưng hai khác quá dài nên dấu ba chấm xuất hiện ở phía bên tay trái.

Tôi muốn có giải pháp chỉ CSS, nhưng JS vẫn ổn nếu không thể tránh được. Sẽ ổn nếu giải pháp chỉ hoạt động trong Firefox và Chrome.

EDIT: Tại thời điểm này, tôi đang tìm cách khắc phục các lỗi trong Chrome ngăn không cho hiển thị đúng khi tài liệu được trộn RTL và LTR. Đó là tất cả những gì tôi thực sự cần ngay từ đầu, tôi chỉ không nhận ra điều đó.

+1

Ouch, hỗn hợp RTL và LTR langages? Tôi đã có rất nhiều vấn đề với điều đó gần đây. Những gì tôi tìm thấy đã giúp rất nhiều khi tôi tách từng phần tử RTL và LTR trong các div khác nhau. Nếu không cả hai ngôn ngữ đã được trộn lẫn trong những cách kỳ lạ một cách đáng kinh ngạc ... – Zwik

+1

FWI: Tôi có một lỗi mở về vấn đề chrome: http://code.google.com/p/chromium/issues/detail?id = 155836 – Mbrevda

+0

có thể trùng lặp của [Cần phải sử dụng "tràn văn bản" khi "hướng" được đặt thành "rtl"] (http://stackoverflow.com/questions/18532256/needs-use-right-text-overflow- khi-direction-is-set-to-rtl) –

Trả lời

14

Cuối cùng tôi đã phải bẻ khóa và làm điều gì đó trong JavaScript.Tôi đã hy vọng rằng ai đó sẽ đưa ra một giải pháp CSS hail-mary nhưng mọi người dường như chỉ bỏ phiếu cho câu trả lời rằng nên là chính xác nếu nó không phải do lỗi của Chrome. j08691 có thể có tiền thưởng cho công việc của mình.

<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

Tôi lấy giải pháp của bạn thêm một bước nữa, vì vậy nó hoạt động khi phần tử được cắt bớt có nhiều hơn một nút văn bản bên trong: http: //jsfiddle.net/bgmort/qSyBU/3/ – undefined

+4

Cảm ơn rất nhiều vì Brian! Tôi chia nhỏ mã của bạn khi tôi cần thứ gì đó thay thế bằng '...' ngay từ đầu, nhưng khi cửa sổ được thay đổi kích thước, và sau đó hoàn nguyên văn bản về trạng thái ban đầu khi cửa sổ được tăng kích thước. Nó có lẽ không phải là thanh lịch nhất, nhưng đây là ngã ba cho bất cứ ai có thể tìm thấy nó hữu ích: http://jsfiddle.net/sP9AE/1/ – Jimbo

+0

Rất đẹp, @ Jimbo. bây giờ có lẽ ai đó có thể tóm tắt nó thành một plugin jQuery. Tôi có thể làm điều đó đôi khi ... – undefined

53

Làm thế nào về một cái gì đó như thế này jsFiddle? Nó sử dụng hướng, sắp xếp văn bản và tràn văn bản để có dấu ba chấm ở bên trái. Theo MDN, có thể có khả năng xác định dấu ba chấm ở bên trái trong tương lai với giá trị left-overflow-type tuy nhiên nó vẫn được xem là thử nghiệm.

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

Đây là kết thúc. Có vẻ tốt trong FF nhưng trong Chrome nó làm cho dòng thứ hai và thứ ba sai. Có vẻ như chỉ cần thêm vào elip và sau đó là clip ở bên phải. – Hemlock

+0

+1 Tôi đã quá chậm. –

+0

@Hemlock - Ồ, theo ví dụ của bạn, phần tử đầu tiên của dòng thứ hai và bốn phần tử đầu tiên của dòng thứ ba sẽ bị cắt? – j08691

0

Dựa trên chỉnh sửa của bạn:

Tại thời điểm này, tôi đang tìm một công việc xung quanh cho các lỗi trong Chrome mà ngăn chặn nó từ render đúng khi một tài liệu là hỗn hợp RTL và LTR. Đó là tất cả những gì tôi thực sự cần ngay từ đầu, tôi chỉ không nhận ra điều đó.

Bạn đã xem xét thuộc tính css unicode-bidi (xem Sitepoint hoặc W3C)? Tôi thực sự chỉ biết về bản thân mình trên another recent post. Đoán của tôi là bạn sẽ muốn sử dụng giá trị embed cho các phần đó theo hướng ngược lại với trang web chính. Vì vậy, trong câu trả lời của j08691, nơi nó là direction: rtl, hãy thêm unicode-bidi: embed vào CSS. Điều này sẽ giải quyết các vấn đề "hỗn hợp RTL và LTR" bạn đang gặp phải.

+0

Tôi đã có hy vọng cao cho điều này nhưng tôi đã cố gắng 'unicode-bidi' [ở đây] (http://jsfiddle.net/ZfbaD/9/) và không có may mắn. – Hemlock

+0

Xin lỗi. Dựa trên các ngày [về điều này] (http://code.google.com/p/chromium/issues/detail?id=2821) (đầu năm 2008, cuối năm 2011), đã có vấn đề với điều này ('rtl' và 'dấu ba chấm') trong một thời gian trong Chrome. Nó gần như xuất hiện như thể nó đã được giải quyết và sau đó có thể nổi lên, nhưng rất khó để nói. – ScottS

+0

@ScottS chắc chắn là một lỗi, vấn đề được gửi tại đây: http://code.google.com/p/chromium/issues/detail?id=155836 – Mbrevda

3

Đó là một lỗi nhỏ, nhưng có lẽ một điểm đúng hướng

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

Điều này là gần. Điều đó thật kỳ lạ làm sao nó thêm dấu chấm lửng vào lúc bắt đầu của từ, nhưng trims từ từ cuối. – Hemlock

+0

Đó cũng là những gì tôi nghĩ. – HerrSerker

0

tôi đặt một số Javascript với nhau để regex ra ba mục và thêm ellipsis trong khi cần thiết. Điều này không rõ ràng nhìn vào bao nhiêu văn bản sẽ phù hợp trong hộp nhưng nếu hộp được cố định này có thể không phải là một vấn đề.

<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 có lẽ là cần thiết để giải quyết vấn đề này. Tôi không thể sử dụng câu trả lời này mặc dù bởi vì tôi không sử dụng jquery và tôi chắc chắn đo lường sẽ là cần thiết. – Hemlock

+0

Có lẽ tốt hơn nên sử dụng '\ u2026' cho ký tự dấu ba chấm, chứ không phải '...' – Spooky

1

Tại sao không chỉ sử dụng direction:rtl;

+3

Do lỗi trong Chrome khi RTL và LTR được trộn lẫn. – Hemlock

1

Sử dụng @Hemlocks, @ Brian Mortenson và @ giải pháp Jimbo, tôi đã xây dựng một plugin jQuery để giải quyết vấn đề này.

Tôi cũng đã thêm hỗ trợ để trả lại giá trị ban đầu bằng cách sử dụng .html() thay vì trả về giá trị nội tại hiện tạiHTML. Hy vọng rằng nó sẽ hữu ích cho ai đó ...

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

Tiến hành sử dụng:

//Call on elements with overflow: hidden and white-space: nowrap 
$('#container>div').trimLeft(); 
//Returns the original innerHTML 
console.log($('#test').html()); 

fiddle

1

Sử dụng đánh dấu một chút phức tạp hơn (sử dụng chỉ số BDI-tag và một khoảng thời gian thêm cho dấu chấm lửng), chúng tôi có thể giải quyết vấn đề hoàn toàn bằng CSS, không cần JS nào cả - trình duyệt chéo (IE, FF, Chrome) và bao gồm giữ dấu câu bên phải:

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

Được cấp, đây là một cái gì đó của một hack, liên quan đến sự tốt lành của phần tử giả. Tuy nhiên, nhóm của chúng tôi đã sử dụng mã này trong sản xuất và chúng tôi chưa gặp bất kỳ vấn đề gì.

Cảnh báo duy nhất là: Chiều cao của đường cần được cố định và màu nền cần được biết rõ ràng (kế thừa sẽ không hoạt động).

1

Nếu bạn không quan tâm việc lập chỉ mục của những văn bản, bạn có thể sử dụng phương pháp này (nó đảo ngược các dòng văn bản):

Nếu bạn có trong văn bản của bạn HTML yếu tố khác ngoài <br> bạn cần phải thực hiện một số sắp xếp để sử dụng phương pháp này.

HTML code:

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

mã CSS:

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

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

Các vấn đề liên quan