I'm trying to detect (via javascript) when text-overflow is in effect. After much research, I have a working solution, except in any version of Firefox:
http://jsfiddle.net/tonydew/mjnvk/
If you adjust the browser so that the ellipsis is applied, Chrome, Safari, even IE8+ will alert that the ellipsis is active. In Firefox (every version I have tried, including 17 and 18) not so much. Firefox will always tell you ellipsis is NOT active.
The console.log() output shows why:
Firefox (OS X):
116/115 - false
347/346 - false
Chrome (OS X):
116/115 - false
347/851 - true
In Firefox, scrollWidth is never greater than offsetWidth.
The closest thing I can find to a solution is "Why are IE and Firefox returning different overflow dimensions for a div?" but I am already using the proposed solution.
Can anyone shed some light on how to make this work in Firefox too please?
$(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/
Anybody have a comment on the efficiency of this? If I have a page of many potential overflow elements, is this going to have negative effects? I'd like to avoid modifying existing markup if I can, but not at the expense of excessive JS processing on each page load.
Check its style. overflow property, if it is 'visible' then the element is hidden. Also, check if its clientWidth is less then scrollWidth or clientHeight is less then scrollHeight then the element is overflowed.
The ellipsis is displayed inside the content area, decreasing the amount of text displayed. If there is not enough space to display the ellipsis, it is clipped. The <string> to be used to represent clipped text. The string is displayed inside the content area, shortening the size of the displayed text.
So, if you've arrived at this question because you're having difficulties getting the ellipsis to operate inside a display: Try adding min-width: 0 to the outmost container that's overflowing its parent, even if you've previously set overflow: hidden to it, and see how it works for you.
Inline overflow occurs when the text in a line overflows the available width without a breaking opportunity. To force overflow to occur and ellipses to be applied, the author must apply the nowrap value to the white-space property on the element, or wrap the content in a <NOBR> tag.
you need to add div inside each td to make it work in 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/
I actually wrote a jQuery plugin to do this. It simply sets the title
of the target element to the entire text if truncated, but you can adapt it for your exact needs:
/**
* @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's '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's '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"
};
And to use, simply include the js and call:
$(".override").truncateText();
This has been used in production, and haven't noticed any ill effects with hundreds of target elements on a page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With