I\'m trying to calculate text width using jQuery. I\'m not sure what, but I am definitely doing something wrong.
So, here is the code:
var c = $(\'.c
the thing, you are doing wrong, that you are calling a method on cTxt, which is a simple string and not a jQuery object. cTxt is really the contained text.
Expanding on @philfreo's answer:
I've added the ability to check for text-transform
, as things like text-transform: uppercase
usually tend to make the text wider.
$.fn.textWidth = function (text, font, transform) {
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'))
.css('text-transform', transform || this.css('text-transform'));
return $.fn.textWidth.fakeEl.width();
};
var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>';
I modified Nico's code to work for my needs.
$.fn.textWidth = function(){
var self = $(this),
children = self.contents(),
calculator = $('<span style="white-space:nowrap;" />'),
width;
children.wrap(calculator);
width = children.parent().width(); // parent = the calculator wrapper
children.unwrap();
return width;
};
I'm using .contents() as .children() does not return text nodes which I needed. I also found that the returned width was impacted by the viewport width which was causing wrapping so I'm using white-space:nowrap; to get the correct width regardless of viewport width.
I could not get any of the solutions listed to work 100%, so came up with this hybrid, based on ideas from @chmurson (which was in turn based on @Okamera) and also from @philfreo:
(function ($)
{
var calc;
$.fn.textWidth = function ()
{
// Only create the dummy element once
calc = calc || $('<span>').css('font', this.css('font')).css({'font-size': this.css('font-size'), display: 'none', 'white-space': 'nowrap' }).appendTo('body');
var width = calc.html(this.html()).width();
// Empty out the content until next time - not needed, but cleaner
calc.empty();
return width;
};
})(jQuery);
this
inside a jQuery extension method is already a jQuery object, so no need for all the extra $(this)
that many examples have.white-space: nowrap
, just to ensure that it measures it as a single line (and not line wrap based on other page styling).font
alone and had to explicitly copy font-size
as well. Not sure why yet (still investigating).@philfreo
does.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