Текстовый многоточие на левой стороне - PullRequest
57 голосов
/ 20 марта 2012

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

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

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

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

РЕДАКТИРОВАТЬ: На данный момент я ищу обходной путь для ошибок в Chrome, которые мешают правильно отображать при смешивании документаRTL и LTR.Это было все, что мне действительно было нужно с самого начала, я просто не осознавал этого.

Ответы [ 9 ]

74 голосов
/ 20 марта 2012

Как на счет этого 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 голосов
/ 30 марта 2012

Мне наконец-то пришлось взломать и сделать что-то в 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

4 голосов
/ 27 марта 2012

Это немного глючит, но, возможно, точка в правильном направлении

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>
3 голосов
/ 03 июня 2014

Почему бы просто не использовать direction:rtl;

1 голос
/ 01 января 2016

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

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

1 голос
/ 03 декабря 2015

Используя немного более сложную разметку (используя bdi-тег и дополнительный интервал для многоточия), мы можем полностью решить проблему в CSS, JS вообще не требуется - кросс-браузер (IE, FF, Chrome) и включая знаки препинания вправо:

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

Конечно, это что-то вроде хака, включающего доброту псевдоэлемента. Однако наша команда использовала этот код в работе, и у нас не было никаких проблем.

Единственное предостережение: высота линии должна быть фиксированной, а цвет фона должен быть известен в явном виде (наследование не будет работать).

1 голос
/ 03 января 2015

Используя решения @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());

скрипка

0 голосов
/ 29 марта 2012

Я собрал немного 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 голосов
/ 27 марта 2012

На основании ваших правок:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...