Calculating text width
Here's a function that's better than others posted because
- it's shorter
- it works when passing an
<input>
,<span>
, or"string"
. - it's faster for frequent uses because it reuses an existing DOM element.
Demo: http://jsfiddle.net/philfreo/MqM76/
// Calculate width of text from DOM element or string. By Phil Freo <http://philfreo.com>
$.fn.textWidth = function(text, font) {
if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
$.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
return $.fn.textWidth.fakeEl.width();
};
This worked better for me:
$.fn.textWidth = function(){
var html_org = $(this).html();
var html_calc = '<span>' + html_org + '</span>';
$(this).html(html_calc);
var width = $(this).find('span:first').width();
$(this).html(html_org);
return width;
};
The textWidth
functions provided in the answers and that accept a string
as an argument will not account for leading and trailing white spaces (those are not rendered in the dummy container). Also, they will not work if the text contains any html markup (a sub-string <br>
won't produce any output and
will return the length of one space).
This is only a problem for the textWidth
functions which accept a string
, because if a DOM element is given, and .html()
is called upon the element, then there is probably no need to fix this for such use case.
But if, for example, you are calculating the width of the text to dynamically modify the width of an text input
element as the user types (my current use case), you'll probably want to replace leading and trailing spaces with
and encode the string to html.
I used philfreo's solution so here is a version of it that fixes this (with comments on additions):
$.fn.textWidth = function(text, font) {
if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').appendTo(document.body);
var htmlText = text || this.val() || this.text();
htmlText = $.fn.textWidth.fakeEl.text(htmlText).html(); //encode to Html
htmlText = htmlText.replace(/\s/g, " "); //replace trailing and leading spaces
$.fn.textWidth.fakeEl.html(htmlText).css('font', font || this.css('font'));
return $.fn.textWidth.fakeEl.width();
};
My solution
$.fn.textWidth = function(){
var self = $(this),
children = self.children(),
calculator = $('<span style="display: inline-block;" />'),
width;
children.wrap(calculator);
width = children.parent().width(); // parent = the calculator wrapper
children.unwrap();
return width;
};
Basically an improvement over Rune's, that doesn't use .html
so lightly