Эллипсис переполнения текста с левой стороны
У меня есть список путей (из-за отсутствия лучшего слова, возможно, дорожки из крошки хлеба лучше описывают их). Некоторые из значений слишком длинны для отображения в их родительском объекте, поэтому я использую text-overflow: ellipsis
. Проблема в том, что важная информация находится справа, поэтому мне хотелось бы, чтобы эллипсис появился слева. Что-то вроде этого искусства ascii:
----------------------------
|first > second > third |
|...second > third > fourth|
|...fifth > sixth > seventh|
----------------------------
Обратите внимание, что первая строка достаточно короткая, поэтому она остается левой, а две другие слишком длинны, поэтому эллипсис появляется с левой стороны.
Я бы предпочел только решение CSS, но JS в порядке, если его не избежать. Это нормально, если решение работает только в Firefox и Chrome.
EDIT: На этом этапе я ищу работу для ошибок в Chrome, которые не позволяют корректно отображать документ в смешанном RTL и LTR. Это все, что мне действительно нужно с самого начала, я просто этого не осознавал.
Ответы
Ответ 1
Наконец-то мне пришлось взломать и сделать что-то в 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
Ответ 2
Как насчет чего-то вроде этого 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>
Ответ 3
Это немного багги, но, может быть, точка в правильном направлении
http://jsfiddle.net/HerrSerker/ZfbaD/50/
<div class="container">
<span class="part">second</span>
<span class="part">></span>
<span class="part">third</span>
<span class="part">></span>
<span class="part">fourth</span>
<span class="part">></span>
<span class="part">fifth</span>
<span class="part">></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;
}
Ответ 4
Почему бы просто не использовать direction:rtl;
Ответ 5
Используя @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());
fiddle
Ответ 6
Используя немного более сложную разметку (используя bdi-тег и дополнительный диапазон для многоточия), мы можем полностью решить проблему в CSS, никакой JS не требуется - перекрестный браузер (IE, FF, Chrome) и включая сохранение знаков препинания вправо:
http://jsbin.com/dodijuwebe/1/edit?html,css,output
Конечно, это что-то вроде взлома, связанного с доброжелательностью псевдоэлемента. Однако наша команда использует этот код в производстве, и у нас не было никаких проблем.
Единственные предостережения: Высота линии должна быть исправлена, а цвет фона должен быть явно известен (наследование не будет работать).
Ответ 7
Если вам не нужна индексация этих текстов, вы можете использовать этот метод (он меняет текстовые строки):
Если в ваших текстах есть другие элементы 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
Ответ 8
На основе вашего редактирования:
На этом этапе я ищу работу для ошибок в Chrome которые препятствуют правильному отображению документа при смешанном RTL RTL и LTR. Это было все, что мне действительно нужно с самого начала, я просто не осознайте это.
Вы просмотрели свойство unicode-bidi
css (см. Sitepoint или W3C)? На самом деле я просто узнал об этом на еще одном недавнем сообщении. Я предполагаю, что вы хотели бы использовать значение embed
для тех частей, которые идут в противоположном направлении к основному сайту. Поэтому в j08691 ответьте, где это direction: rtl
добавьте unicode-bidi: embed
в CSS. Это должно решить проблемы смешанного RTL и LTR, которые у вас есть.
Ответ 9
Я добавил некоторый 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 > second > third<br />
second > third > fourth > fifth > sixth<br />
fifth < sixth < seventh < eighth < 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>