Strings
Javascript String Ellipse to Length
by webdood on Apr.10, 2012, under Canvas, Javascript, Software Development, Strings
A perennial problem with HTML is correctly dealing with ellipsis on text. There is the text-overflow:ellipsis trick, but there are some situations where you need to ellipse a string at a certain number of pixels.
I think I have come up with a pretty clever solution to this.
By adding a prototype to the String Object and using a dynamically generated <canvas> tag, we can accurately measure the width of a string based on a provided font and fontSize, adding ellipsis as necessary.
UPDATE
I was asked by an associate if there was a way to retain the original value of the string before it was ellipsed. In answer to that, I added the lines in red.
Now there is a property called “.originalValue” added to each string that has been ellipsed.
////////////////////////////////////////////////////////////////////////////////
//
// String.ellipseToLength(int length, OPTIONAL string fontSize, OPTIONAL string fontFamily)
// ======================
// Returns an ellipsed string measured to length using CANVAS's measureText method
// By passing in fontSize and FontFamily, you will get accurate measurements
//
////////////////////////////////////////////////////////////////////////////////
String.prototype.ellipseToLength = function( length, fontSize, fontFamily) {
var bContinue = true,
ctx = document.createElement('canvas').getContext('2d'),
measuredLength,
originalValue = retVal = this.toString(),
firstChar = retVal.charAt(0);
fontSize = (typeof fontSize==="undefined") ? "12pt" : fontSize;
fontFamily = (typeof fontFamily==="undefined") ? "Arial" : fontFamily;
ctx.font = fontSize + " " + fontFamily;
if ((typeof length==="undefined") || length===0 || retVal.length===0 || ctx.measureText(firstChar).width >= length) { // Special weird case the first character is greater than the length asked for ...
retVal = "...";
} else {
measuredLength = ctx.measureText(retVal).width;
if (measuredLength > length) { // If the measured length of the string is larger than that specified, then more work is required
while (bContinue) {
retVal = retVal.slice(0,-1);
measuredLength = ctx.measureText(retVal + '...').width;
if (measuredLength <= length) {
retVal = retVal + '...';
bContinue = false;
}
if (retVal.length===0) {
retVal = "..."
bContinue = false;
}
}
}
}
retVal.__proto__.originalValue = originalValue;
return retVal;
}



