Обнаружение переполнения текста CSS: эллипсис в Firefox
Я пытаюсь обнаружить (через javascript), когда текстовое переполнение действует. После долгих исследований у меня есть рабочее решение, за исключением любой версии Firefox:
http://jsfiddle.net/tonydew/mjnvk/
Если вы настроите браузер так, чтобы применялось многоточие, Chrome, Safari и даже IE8 + будут предупреждать, что многоточие активно. В Firefox (каждая версия я пробовал, в том числе 17 и 18) не так много. Firefox всегда будет говорить, что эллипс НЕ активен.
Результат console.log() показывает, почему:
Firefox (OS X):
116/115 - false
347/346 - false
Chrome (OS X):
116/115 - false
347/851 - true
В Firefox scrollWidth никогда не превышает offsetWidth.
Ближайшая вещь, которую я могу найти для решения, - "Почему IE и Firefox возвращают разные размеры переполнения для div?", но я уже использую предлагаемое решение.
Может кто-нибудь пролить свет на то, как сделать эту работу в Firefox тоже, пожалуйста?
<ч/" > EDIT: В дополнение к @Cezary ниже, я нашел метод, который не требует изменений в разметке. Тем не менее, он делает немного больше работы, потому что он временно клонирует каждый элемент для измерения:
$(function() {
$('.overflow').each(function(i, el) {
var element = $(this)
.clone()
.css({display: 'inline', width: 'auto', visibility: 'hidden'})
.appendTo('body');
if( element.width() > $(this).width() ) {
$(this).tooltip({
title: $(this).text(),
delay: { show: 250, hide: 100 },
});
}
element.remove();
});
});
http://jsfiddle.net/tonydew/gCnXh/
Кто-нибудь есть комментарий об эффективности этого? Если у меня есть страница с множеством потенциальных элементов переполнения, будет ли это иметь негативные последствия? Я бы хотел избежать изменения существующей разметки, если можно, но не за счет чрезмерной обработки JS при каждой загрузке страницы.
Ответы
Ответ 1
вам нужно добавить div внутри каждого td, чтобы он работал в firefox,
<td class="first"><div>Here is some text</div></td>
<td class="second">
<div>Here is some more text. A lot more text than
the first one. In fact there is so much text you'd think it was a
waste of time to type all ofit.
</div>
</td>
CSS
td div {
white-space: nowrap;
text-overflow: ellipsis;
overflow:hidden;
width:100%;
}
Jsfiddle
http://jsfiddle.net/mjnvk/7/
Ответ 2
На самом деле я написал плагин jQuery для этого. Он просто устанавливает title
целевого элемента на весь текст, если усечен, но вы можете адаптировать его для ваших конкретных потребностей:
/**
* @author ach
*
* Sets the CSS white-space, overflow, and text-overflow properties such that text in the selected block element will
* be truncated and appended with an ellipsis (...) if overflowing. If the text is truncated in such a way, the
* selected element 'title' will be set to its full text contents and the cursor will be set to 'default'.
* For this plugin to work properly, it should be used on block elements (p, div, etc.). If used on a th or td element,
* the plugin will wrap the contents in a div -- in this case, the table 'table-layout' CSS property should be set to 'fixed'.
*
* The default CSS property values set by this plugin are:
* white-space: nowrap;
* overflow: hidden;
* text-overflow: ellipsis
*
* @param cssMap A map of css properties that will be applied to the selected element. The default white-space,
* overflow, and text-overflow values set by this plugin can be overridden in this map.
*
* @return The selected elements, for chaining
*/
$.fn.truncateText = function(cssMap) {
var css = $.extend({}, $.fn.truncateText.defaults, cssMap);
return this.each(function() {
var $this = $(this);
//To detect overflow across all browsers, create an auto-width invisible element and compare its width to the actual element's
var element = $this.clone().css({display: 'inline', width: 'auto', visibility: 'hidden'}).appendTo('body');
if (element.width() > $this.width()) {
//If a th or td was selected, wrap the content in a div and operate on that
if ($this.is("th, td")) {
$this = $this.wrapInner('<div></div>').find(":first");
}
$this.css(css);
$this.attr("title", $.trim($this.text()));
$this.css({"cursor": "default"});
}
element.remove();
});
};
$.fn.truncateText.defaults = {
"white-space" : "nowrap",
"overflow" : "hidden",
"text-overflow" : "ellipsis"
};
И для использования просто включите js и вызовите:
$(".override").truncateText();
Это было использовано в производстве и не заметило каких-либо побочных эффектов с сотнями целевых элементов на странице.