WEBDOOD.COM

Archive for April, 2012

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;
}
Leave a Comment more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Blogroll

A few highly recommended websites...

  • A List Apart
  • Dive into HTML5
  • Javascript: The Good Parts
  • QuirksMode.org