2012-03-20 3 views
38

У меня есть список путей (из-за отсутствия лучшего слова, возможно, дорожки из крошки хлеба лучше описывают их). Некоторые из значений слишком длинны для отображения в их родительском объекте, поэтому я использую text-overflow: ellipsis. Проблема в том, что важная информация находится справа, поэтому мне хотелось бы, чтобы эллипсис появился слева. Нечто подобное этому искусству ASCii:Эллипсис с переполнением текста на левой стороне

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

Обратите внимание, что первая строка достаточно короткая, так что остается левым краем, но остальные два слишком долго, так что на левой стороне появляется многоточие.

Я бы предпочел только решение CSS, но JS в порядке, если его не избежать. Это нормально, если решение работает только в Firefox и Chrome.

EDIT: На данный момент я ищу работу с ошибками в Chrome, которые предотвращают ее правильное отображение, когда документ смешан с RTL и LTR. Это все, что мне действительно нужно с самого начала, я просто этого не осознавал.

+1

Ouch, смешанные RTL и LTR langages? У меня было много проблем с этим в последнее время. То, что я нашел, помогло многим, когда я разделял каждый элемент RTL и LTR в разных div. В противном случае оба langage были смешаны в отношении странных способов ... – Zwik

+1

FWI: У меня есть ошибка, открытая по проблеме chrome: http://code.google.com/p/chromium/issues/detail?id = 155836 – Mbrevda

+0

Возможный дубликат [Требуется использование права «переполнение текста», когда для «direction» установлено значение «rtl»] (http://stackoverflow.com/questions/18532256/needs-use-right-text-overflow- когда-direction-is-set-to-rtl) –

ответ

14

Мне наконец-то пришлось взломать и что-то сделать в JavaScript.Я надеялся, что кто-то придумает решение для града Мэри, но люди, похоже, просто голосуют за ответ, что должен быть правильным, если бы не ошибки 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

+4

Большое спасибо за это Брайан! Я искал ваш код, поскольку мне было нужно что-то, что заменило бы с помощью «...» в начале, но также и при изменении размера окна, а затем вернет текст обратно в исходное состояние, когда окно будет увеличено по размеру. Это, наверное, не самый элегантный, но вот вилка для тех, кто может найти это полезным: http://jsfiddle.net/sP9AE/1/ – Jimbo

+0

Очень приятно, @Jimbo. теперь, возможно, кто-то может абстрагировать его в плагин jQuery. Я мог бы это сделать когда-нибудь ... – undefined

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

+0

+1 Я был слишком медленным. –

+0

@Hemlock - О, так что согласно вашему примеру, первый элемент второй строки и первые четыре элемента третьей строки должны быть обрезаны? – j08691

0

На основе вашего редактирования:

На данный момент я ищу для работы вокруг ошибок в Chrome , которые предотвращают его от оказания должным образом, когда документ смешанный RTL и LTR. Это было все, что мне действительно нужно было с самого начала, я просто не сделал этого .

Вы смотрели в собственность unicode-bidi Css (см Sitepoint или W3C)? Я на самом деле просто узнал об этом сам по телефону another recent post. Я предполагаю, что вы захотите использовать значение embed для тех частей, которые идут в противоположном направлении к основному сайту. Поэтому в ответе j08691, где находится direction: rtl, добавьте unicode-bidi: embed в CSS. Это должно решить проблемы смешанного RTL и LTR, которые у вас есть.

+0

У меня были большие надежды на это, но я попробовал 'unicode-bidi' [здесь] (http://jsfiddle.net/ZfbaD/9/) и не повезло. – Hemlock

+0

Извините. Исходя из дат [об этом] (http://code.google.com/p/chromium/issues/detail?id=2821) (в начале 2008 года, внизу 2011 года), были проблемы с этим ('rtl' и 'ellipsis') некоторое время в Chrome. Он кажется почти таким, как будто он был решен, а затем, возможно, всплыл, но это трудно сказать. – ScottS

+0

@ScottS там определенно ошибка, вопрос здесь: http://code.google.com/p/chromium/issues/detail?id=155836 – Mbrevda

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

+0

Вот что я и подумал. – HerrSerker

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

+0

Возможно, лучше использовать «\ u2026» для символа многоточия, а не «...» – Spooky

1

Почему бы не только с помощью direction:rtl;

+3

Из-за ошибок в Chrome, когда RTL и LTR смешаны. – Hemlock

1

Использование @Hemlocks, Мортенсон и @ Брайан @ решений Джимбо, я построил плагин JQuery, чтобы решить эту проблему.

Я также добавил поддержку, чтобы вернуть начальное значение с помощью .html() вместо того, чтобы вернуть текущий внутреннийHTML. Надеюсь, это будет полезно для кого-то ...

(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

Если вы не заботитесь индексации этих текстов, вы могли бы использовать этот метод (он переворачивает строки текста):

Если у вас есть в ваших текстах других 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

Смежные вопросы