Calculating text width

后端 未结 22 1360
轻奢々
轻奢々 2020-11-22 03:36

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         


        
相关标签:
22条回答
  • 2020-11-22 03:45

    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.

    0 讨论(0)
  • 2020-11-22 03:45

    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();
    };
    
    0 讨论(0)
  • 2020-11-22 03:49
    var calc = '<span style="display:none; margin:0 0 0 -999px">' + $('.move').text() + '</span>';
    
    0 讨论(0)
  • 2020-11-22 03:50

    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.

    0 讨论(0)
  • 2020-11-22 03:51

    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);
    

    Notes:

    • this inside a jQuery extension method is already a jQuery object, so no need for all the extra $(this) that many examples have.
    • It only adds the dummy element to the body once, and reuses it.
    • You should also specify white-space: nowrap, just to ensure that it measures it as a single line (and not line wrap based on other page styling).
    • I could not get this to work using font alone and had to explicitly copy font-size as well. Not sure why yet (still investigating).
    • This does not support input fields that way @philfreo does.
    0 讨论(0)
  • 2020-11-22 03:54

    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

    0 讨论(0)
提交回复
热议问题