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.
Have a fresh tip? Share with Coderwall community!
JavaScript on a page runs with the privileges of that origin. One altered library, tag manager, or snippet can read inputs, change what people see, and call your APIs as the user.
Security insights from Cside