Calculate text dimensions of DOM element
Forked from good idea here: https://coderwall.com/p/kdi8ua - see discussion in comments.
Just playing around, but calculates either width or height of multiple elements:
Updated per "other styles" comment
// get width or height
!(function($) {
var N = function(key) { return 'getTextSize.' + key; },
fontMapping = function($o, font) {
//return {"font": font.font || $o.css('font')};
var result = {}; // don't affect original object
$.each(font, function(prop, val) {
result[prop] = (val || $o.css(prop));
});
return result;
}
;
$.fn.getTextSize = function(dimension, text, font) {
dimension = (dimension || 'width');
// figure out what font aspects we're concerned with
if( typeof font === "string" ) {
font = {"font": font};
}
// include other common style properties that affect sizing
font = $.extend({"font": false, "text-transform": false, "letter-spacing": false}, font);
// allow multiple calculations
return $.map($(this), function(o) {
var $o = $(o), $fake = $o.data(N('fake'));
console.log($o, $fake);
if (!$fake) {
// cloning causes duplication issues on subsequent calls
// can attach to parent, but may be unnecessary parsing vs. body if updating font each time
$fake = $('<span>').hide().addClass('placeholder').empty().appendTo(document.body);
$o.data(N('fake'), $fake);
}
return $fake.html(text || $o.val() || $o.text()).css(fontMapping($o, font))[dimension]();
});
};
})(jQuery);
Usage:
$('.multiple-elements').getTextSize().join('px, ')+'px';
$('.single').getTextSize('height')[0];
Written by Jeremy
Related protips
4 Responses
You should also take into account styles like line-height
, text-transform
, letter-spacing
Yeah I was thinking about that with the .clone
+adjacent idea, now need to do it manually. Good call.
Update font
seems to include line-height
at least. I've added an option to extend the font
value passed to include other properties
Can you describe the reasons for each change over https://coderwall.com/p/kdi8ua? Is it purely performance (if so, how) or improved in some other way?
@philfreo -- mostly because i like rewriting stuff; there wasn't anything wrong with your post. i did:
- wrap it in a closure because everybody loves closures
- allow you to call the plugin on multiple elements (i.e.
$('p').getTextSize()
would work "correctly" on multiple paragraphs, as they could differ) - get width or height (rather than just width)
- or get any font property rather than just 'width' and 'height'
you can kinda see a comparison in the fiddle.